shell基础知识

shell介绍

shell介于内核与用户之间,负责命令的解释。

shell类型

[root@localhost ~]# cat /etc/shells   查看shell种类
/bin/sh                    是bash shell的一个快捷方式
/bin/bash                 bash shell 是大多数Linux默认的shell,功能齐全
/usr/bin/sh               
/usr/bin/bash
/bin/tcsh                  是csh的增强版 ,完全兼容csh
/bin/csh                   具有C语言风格的一种shell 
/sbin/nologin 非交互 ,不能登录操作系统

shell脚本格式

复制代码
#!/bin/bash
//第一行 #!魔法字符,指定代码的执行程序,即告诉系统用什么解释器(用那种shell)
//脚本基本信息描述
#name:名字
#describe:描述用途
#Path:存放路径
#usage:用法
#update:更新时间
//脚本具体内容
.......
复制代码

shell脚本执行方法

 标准执行:

shell脚本必须要有可执行权限

chmod +x 脚本文件 (加可执行权限)

绝对路径执行:/shell10/shell1.sh

相对路径执行:./shell1.sh

非标准执行:

shell脚本可以不要可执行权限

bash shell1.sh

bash -x 脚本名 查看脚本执行过程

bash -n 脚本名 查看脚本是否有语法错误

source shell1.sh

. shell1.sh(.后有个空格)

****除了绝对路径执行外,其他的执行命令必须在脚本所在目录下执行

 

bash的基本特性

常见快捷键

ctrl +c 终止某个操作

  z   将前台运行的程序挂到后台

  d 退出 等于exit

  1 清屏等于clear

  a 光标移动到命令行最前端

  e 光标移动到命令行最后端

  u 删除光标前所有字符

  k删除光标后所有字符

  r 搜索历史命令(输入关键字即可)

常用通配符

*  :匹配0或多个字符    

? :匹配任意单个字符

[list] :匹配[list]中的任意单个字符或者一组单个字符  file[abc]  匹配filea或fileb或filec, file[1-47] 匹配file1到file4和file7 (-必须后边的大于前边的)

[!list] :匹配除[!list]中的任意单个字符 或一组单个字符[!abc]  匹配除filea、fileb、filec 外的任意file加一个字符

{string1,string2,.......} :匹配string1,string2 ,或更多字符  file{3..6}(必须要两个点) 匹配file3 file4 .....file6 or file{3,4,5,6}

例子:有两个文件file1 ,file11

ls -l fi*  或者 flile*能匹配到两个文件  ls -l file1* 能匹配到file1

但ls -l file1? 匹配不到file1 且 ls -l fil? 匹配不到连个文件 只有ls -l file? 匹配到file1 ls -l file1?匹配到file11 

bash中的引号

双引号""  :会把引号内的内容当成整体来看,允许通过$符合引用其他变量值

单引号''  : 会把引号内的内容当成整体来看,禁止引用其他变量值,shell中特殊符号都被视为普通字符

反撇号`` :反撇号和$()一样,引号或括号里的命令会优先执行,如果存在嵌套,反撇号不能用

echo "$(date +%F)" = echo "`date +%F`"

echo `echo "`date +%F`"`  这就是嵌套,是不允许的会报错,可以改为 echo  $(echo "`date +%F`")

重命名文件

mv 只能重命名单个文件 (多个就会当成移动文件)

把file1-3重命名为text1-3

rename  file text  file?

把file11-13 重命名为text11-13

rename file1 text file1? or   rename file text file??

变量的定义

1、变量的分类

本地变量:当前用户自定义的变量,当前进程中有效,其他进程即当前的子进程无效。

环境变量:当前进程有效,并且能够被子进程调用

全局变量:全局所有用户和程序都能调用,且继承、新建的用户也能调用。

查看当前用户的环境变量: env |grep ^A

查看当前用户的所有变量:set

临时将临时(本地)变量变成环境变量:export A=hello

永久生效:vim /etc/profile 末尾加上 export A=hello 重新加载此文件source /etc/profile 

第三方软件配置环境变量

which 软件名 找到命令所在文件

vim /etc/profile 末尾加上

export PATH="$PATH:/usr/local/mysql/bin:第二个路径" (加export是环境变量,不加则是本地变量)

系统变量(内置bash中的变量):shell本身已经固定好了其名字和作用

$? :上一条命令执行后的返回状态,返回值为0表示正常,非零为出异常或出错

0 命令成功结束
1 通用未知错误
2 误用shell命令
126 找到命令,但命令不可执行(权限不够)
127 没找到命令
128 无效退出参数
128+x Linux 信号x的严重错误
130 Linux 信号2 的严重错误,即命令通过SIGINT(Ctrl+C)终止
255 退出状态码越界

$$ :当前所在进程的进程号   kill -9 `echo $$` 杀死当前进程

$! :后台运行的最后一个进程号  echo $!

!$:调用最后一条命令历史中的参数

!!:调用最后一条历史命令

$#:脚本后面接的参数个数

$*:脚本后面所有参数,参数当成一个整体输出,每一个变量参数之间以空格隔开

$@:脚本后面所有的参数,参数是独立的,也是全部输出

$0:当前执行的进程/程序名

$1~$9:位置参数变量

${10}~${n} :扩展位置参数变量,第十个位置变量必须用{}括起来

变量定义

1、默认情况下,shell里定义变量是不分类型的,可以给变量赋予任何类型的值;等号两边不能有空格,对于有空格的字符串作为赋值时,要用引号引起来。变量名=变量值

2、变量的获取方式:$变量名

A=123456

echo $A or echo ${A}

都显示:123456

echo ${变量名:从第几个字符截取:截取的字符个数}

echo ${A:2:3}  ***第二段为下标,从0开始。下标0对应A中第一个字符,第三段表示显示几个字符***

显示为:345

unset 变量名 :删除变量

变量定义规则

shell中变量名区分大小写,A =123 a=456 这是两个变量。

shell中变量重新赋值后会覆盖,先定义A=123,后定义A=456 最后A的变量值为456

shell中变量名不能以数字开头,也不能有特殊字符,如? $ *等

shell中可以把一个命令的执行结果赋值给一个变量

自己定义有类型的变量

declare 选项 变量名=变量值

  • -f  仅显示函数。
  • -r  将变量设置为只读。
  • -x  指定的变量会成为环境变量,可供shell以外的程序来使用。相当于用export 变量名 进行导出
  • -i  [设置值]声明变量为整数型   "+r"则是取消变量所设的属性。
  • -a    指定为索引数组(普通数组)
  • -A   指定为关联数组

如:declare -r A=123  :设置变量为只读,此时,想要再设置A变量进行覆盖是不行的。unset A也不能删除变量

取消只读:

# cat << EOF| gdb
> attach $$
> call unbind_variable("test")   test为变量名
> detach
> EOF

数组

普通数组:只能使用整数作为数据索引(元素下标)

关联数组:可以使用字符串作为数组索引(元素的下标)

普通数组定义:用括号来表示数字,数组元素(变量)用空格符号分割开,

定义数组的一般形式为:

变量名=变量值

array[0]=v1   数组下标0赋值为v1

array[1]=v2  数组下标1赋值为v2

array[2]=v3

or

array=(v1 v2 v3)  数组下标0 ,1, 2,赋值为 v1 ,v2, v3 

array1=(`cat /etc/passwd`) or array1=($(cat /etc/passwd))把passwd中每一行赋值给array1数组

array2=(1 2 3 "hello word" [10]=linux)   ""里为一个元素  []=元素 :指定元素下标

echo ${array[*]} :获取数组所有元素,也可以用@

echo ${array[1]} :获取数组下标1的元素

echo ${array[*]:1:2} :获取数组从下标1开始,后两个下标的元素,即下标1下标2的值,是v2 v3

数组变量也会覆盖(只会覆盖再定义的下标的元素)

如:再定义 array[0]=m1 array[10]=m2

则数组array='(array[0]=m1 array[1]=v2 array[2]=v3 array[10]=m2)'

获取数组里的元素个数:echo ${#array[*]}  /数组长度

获取数组里有元素值的下标号 :echo ${!array[*]}

关联数组定义:

首先声明关联数组

declare  -A array10

数组赋值:

数组名[索引下标]=变量值

一次赋一个值:

array10[linux]=one

array10[java]=two

一次赋多个值:

array10=([linux]=one [java]=two [name]="feng xue")

查看关联数组:

declare -A

echo ${array10[*]} :获取关联数组的所有元素,其是无序的 。@也可

echo ${array10[name]} :获取固定数组下标的元素

echo ${#array10[*]} :获取关联数组里的元素个数/数组长度

echo ${!array10[*]} :获取关联数组里的下标值

交互式定义变量的值 read 让用户去定义变量的值

-p 定义提示信息

-n 字符数(限制变量值的字符)

-s 不显示

-t 超时(默认单位为秒)(限制用户输入变量的超时时间)

read -p "提示信息如:input your name:"  name

read -s -p "input your passwd:"  passwd       你输入的字符不在屏幕上显示

read -n 3 "input your name:"  name 只能输入三个字符如abc

read -t 3 "input your name:"  name    三秒后退出输入界面,三秒内没有回车确认不会给变量赋值

#read A B

hello world

上边A赋值hello B赋值world

#read A B < 1.txt 从文件中获取值 1.txt内容为hello world 

上边A赋值hello B赋值world

注意:read A B 赋值多个变量时 只有遇到空格后才会分别赋值两个变量,若1.txt内容为hello:world 变量A值为hello:world B为空

其他变量(扩展)

1、取出一个目录下的目录和文件:dirname和basname

2、变量内容的删除和替换

  一个"%"代表从右往左去掉一个/key/

  两个"%%"代表从右往左去掉最大的一个/key/

  一个"#"代表从左往右去掉一个/key/

  两个"##"代表从左往右去掉最大的一个/key/  

${变量名#关键字符} 如果变量内容从头开始的数据符合"关键字符",则将符合的最短数据删除
${变量名##关键字符} 如果变量内容从头开始的数据符合"关键字符",则将符合的最长数据删除
${变量名%关键字符} 如果变量内容从尾开始的数据符合"关键字符",则将符合的最短数据删除
${变量名%%关键字符} 如果变量内容从尾开始的数据符合"关键字符",则将符合的最长数据删除

#A=/root/desktop/shell/mem.txt  定义变量为此目录

#dirname $A   取出目录

/root/desktop/shell

#basname $A  取出文件

mem.txt

#url=www.taobao.com

#echo ${#url}  获得变量长度

#echo ${url#*.}   #从左往右最短匹配  *.表示关键字

taobao.com

#echo ${url##*.}  #从左往右最长匹配

com

#echo ${url%.*}         #从右往左最短匹配

www.taobao

#echo ${url%%.*}  #从右往左最长匹配

www

替换

${变量名/旧字符串/新字符串} 表示若变量内容符有旧字符串则第一个旧字符串会被新字符串替换
${变量名//旧字符串/新字符串} 表示若变量内容有旧字符串则全部旧字符串会被新字符串替换

 

#echo ${url/taobao/wangyi}

www.wangyi.com

#echo ${url//o/i}

www.taibai.cim

Shell变量的替代

给Shell变量设置默认值的格式为${变量名-新的变量值}or${变量名=新的变量值},如果变量名没有被赋值,会使用新的变量值替代,如果已被赋值(包括空值),则该值不会被替代。

${变量名:-新的变量名}
这样如果变量为空值也会被替代

 

 简单的四则运算

算术运算:默认情况下,shell就只能支持简单的整数运算

+ - * / %   (/求商 %取余数)

bash shell中算数运算有四种方式

1、使用$(())   echo $((5/10))   得0 echo $((5%10))  得5

2、使用$[]  echo $[5*10]   50  echo $[5/10]   0

3、使用expr 外部程式  exper 3 +(-,/,%) 2   expr 2  \* 3  等于6   乘号比较特殊需要转义一下 数字 符号 数字间得有空格,不然就直接输出字符串:expr 2*3 输出:2*3

4、使用let命令 let n=n+(-,%,/,*)1 等于 let n+(-,%,/,*)=1    let n=n**2(求n的2次方) let n=n**3(4,5,6....)(n的三(4,5,6...)次方) 

如何算小数 bc

echo 1+1.5 |bc  (跟bc的话,数字 符号 数字间可以没有空格)

还可以直接输bc进入其中计算

复制代码
[root@localhost ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
2.4*4.5       (输入计算)
10.8        (结果)
5/2
2
^C
(interrupt) Exiting bc.
复制代码

i++与++i的区别

对变量值无影响:i=1,j=1,let i++ =let j++ 值是一样的

对表达式的值有影响:

let x=i++     i++ 先赋值后运算(先把i的值给x,i再加一)

let y=++j   ++j 先运算后赋值 (j先加一。再把j的值给y)

上边i=2 j=2 但x=1,y=2

 

posted @   忆笙歌  阅读(135)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示