导图社区 shell
基础篇的shell编程和用法分享~包括变量,shell数组,注释,输出服,流程,命令,运算符,函数,参数的传递,符号。满满知识点干货~
编辑于2023-02-21 09:26:17 广东shell编程
变量
类型
局部变量
在脚本或函数中定义的变量
环境变量
全局都可以用的变量
shell变量
shell程序设置的特殊变量,既有局部变量,也有环境变量
字符串
注意:等号两边不能有空格,否则出错
创建
单引号
注意
任何字符和变量只能按原样输出
不能出现单个引号,但可以出现多对单引号拼接
例
var='this is $(ls .)' this is $(ls .)
双引号
注意
里面可以使用转义字符和变量
例
var="this `ls .`" this is $(ls .)
拼接字符串
]$ your_name="liuy" ]$ name1="hello,${your_name}\!" ]$ name2="hello,$your_name\!" ]$ echo ${name1} ${name2} #有空格 hello,liuy\! hello,liuy\!
获取字符串的长度
]$ str="liuxie" ]$ echo ${#str1} 6
提取子字符串
]$ name1="my name is liuxie." ]$ echo ${name1:0:6} #提取第1到第6个字符 my nam
查询字符串中 某个字段的位置
]$ str="www is a greate site" ]$ echo `expr index "$str" io` 5 #查到i或o字段的位置,哪个先出现查哪个
显示
echo $var
echo ${var} #推荐
只读模式
readonly var #启动只读模式 var="nmber" #会报错
删除
unset var
shell数组
定义
一行定义
]$ array_name=(12 33 2 34 87)
多行定义
]$ ary1=(12 > 23 > 34 > 56)
单独定义
]$ ary2[0]=11 ]$ ary2[3]=45
读取数组
单个读取
${ary1[n]} 获得第n+1个数字 ]$ echo ${ary1[2]} 34 #读取第三个数字
全部读取
]$ echo ${ary1[@]} 12 23 34 45 56
其他
获取数组长度 或个数
]$ echo ${#ary1[@]} 或 ]$ echo ${#ary1[*]}
单个元素的长度
]$ echo ${#ary1[2]} 2 #第3个元素的长度
注释
单行注释
#---------------------- # 这是一个注释 # author:liuxie #----------------------
多行注释
<<EOF echo "this is EOF notes." EOF 或 <<! echo "this is ! notes." !
输出符
printf
输出不会像echo一样换行
]$ printf "test text" test text[liu@liu ~]$
格式替代符
可能是格式化数据 看起来更好看
%s
必须是字符串或字符型
]$ printf "%-10s %-10s\n" 媒体 分流 媒体 分流 #10是指留10个空格
%c
必须是字符型或字符串
此类型不支持中文
%d
必须是整数
%f
必须是数字
流程
if...else
if [ ${a} -gt ${b} ] then echo "a 大于b" elif test ${a} -lt ${b} then echo "a 小于b" else echo "a 等于b" fi
for循环
普通循环
#语法一 for 变量 in 值1 值2 值3.. do 程序块儿 done
#!/bin/bash for i in 1 2 3 4 5 do #uptime命令先执行 echo "${i}-->$(uptime)" done
命令循环
for 变量 `命令` do 程序块儿 done
#!/bin/bash for i in $(ls ../tz/*.tar.gz) do tar -xzvf $i >/dev/null done
数学循环
#语法三 for ((初始值; 循环控制; 变量变化)) do 程序块儿 done
#求1到100的和 #!/bin/bash sum=0 for (( i=1; i<101; i++ )) do sum=$(( $sum + $i )) done echo "1+2+...+100=$sum"
while循环
普通
while condition do command done
#!/bin/bash #打出1到5的数字 i=1 while [ $i -le 5 ] #or while(($i<=5)) do echo $i let "i++" done
求100内能被 4整除的数
子主题
until循环(与while相反) 一般while优于until 少数情况相反
语法
until condition do command done
例如
输出1到5
#!/bin/bash i=1 until [ $i -gt 5 ] do echo ${i} let i++ done
case语句
语法
case ${i}(值) in 值1) command1 command2 ;; 值2) commmand1 ;; *)#都没有选 command3 ;; esac
例子
#!/bin/bash echo "请输入1到4之间的整数" read i case ${i} in 1) echo "你选择的是1" ;; 2) echo "你选择的是2" ;; 3) echo "你选择的是3" ;; *) echo "你选择的是4或之外的数据" ;; esac
break语句
说明
退出整个循环
例子
#!/bin/bash while : do read i echo "请输入1到4的数字" case $i in 1|2|3|4) echo "你输入的$i" ;; *) echo "你输入的不是1到4的数字" break ;; esac done
continue语句
说明
退出本次循环
命令
算数运算
let
i=10 let i++
let i--
let i=i+10 let i+=10
let i=i-10 let i-=10
test
if test $i -eq $j then
seq
seq 3
1 2 3
运算符
其中,[ ]和test命令有点相同 if [ ${a} -eq ${b} ] then if test ${a} -eq ${b} then if(($a==$b)) then
注意事项
所有运算中,符号与数字得分隔开 expr 10 + 20(正确,结果为30) expr 10+20(错误) [ 10 == 20 ](正确) [10==20](错误)
算术运算
expr
a=20 b=10 c=3
加、减、乘、除
expr 10 + 20
expr 10 \* 20
expr 10 - 20
expr 10 / 20
取余
`expr ${a} % ${c}`
赋值
`expr b = ${a}`
判断相等
expr $a == $b #相等则为1,否则0
判断不相等
expr $a != $b #相等则为1,否则0
关系运算
if [[ ${a} -le ${b} ]] then echo "a <= b" else echo "a > b" fi
相等
[ $a == $b ] [[ ${a} == ${b} ]]
[ $a -eq $b ]
不相等
[ $a != $b ] [[ $a != $b ]]
[ $a -ne $b
大于
[ $a -gt $b ]
[[ ${a} > ${b} ]]
小于
[ $a -lt $b ]
[[ ${a} < ${b} ]]
大于等于
[ $a -ge $b ]
小于等于
[ $a -le $b]
布尔运算
非
!
[ ! false ] #返回true
或
-o
[ $a -lt 20 -o $b -gt 100] #返回true
与
-a
[ $a -lt 20 -a $b -gt 100 ] #返回false
逻辑运算
或
||
[ $a -lt 20 || $b -gt 100] #返回true
与
&&
[ $a -lt 20 && $b -gt 100 ] #返回false
字符串运算符
a="abc" b="acd" c="abc"
判断相等
=
[ $a = $b] #返回fasle
判断不相等
!=
[ $a != $b ] #返回true
字符串长度是否为0
-z
[ -z $a ]
字符串长度是否不为0
-n
[ -n $a ]
字符串是否为空
str
[ ${a} ]
文件测试运算符
检测文件(目录)是否存在,true为存在
[ -e file ] [ -e /var/log/message ]
文件是否为目录,是则true
[ -d file ]
文件是否为普通文件,是则true
[ -f file ]
文件是否是块设备文件,是则true
[ -b file ]
文件是否是字符设备文件,是则true
[ -c file ]
检测文件是否为空,不为空为true
[ -s file ]
文件是否可读,是则true
[ -r file ]
文件是否可写,是则true
[ -w file ]
文件是否可执行,是则true
[ -x file ]
文件是否设置SUID,是则true
[ -u file ]
文件是否设置SGID,是则true
[ -g file ]
文件是否有名管道,是则true
[ -p file ]
文件是否设置了粘着位(Sticky Bit),是则true
[ -k file ]
函数
语法
[ function ] 函数名() { action; [ return int; ] } 函数名 #执行函数
中括号表示可有可无
例子
#!/bin/bash demoFun(){ echo "你好,世界!" echo "这是第一个函数!" echo "你好,再见,世界" } demoFun
参数的传递
设置参数
chmod +x te1.sh #使脚本可执行 ./te1.sh 1 2 3 #传递1,2,3这3个参数
特殊字符
第1个参数的值
$1
显示全部参数
$* $@(但是要加引号)
脚本当前的进程号
$$
后台运行的最后一个进程号
$!
显示最后命令的退出状态 0表示没有错误,其它有错误
$?
显示Shell使用的当前 选项,与set命令功能相同。
$-
传递到脚本的参数个数
$#
符号
通配符
shell会将其当作路径或文件名去在磁盘上搜寻可能的匹配:若符合要求的匹配存在,则进行代换(路径扩展);否则就将该通配符作为一个普通字符传递给“命令”,然后再由命令进行处理。 总之,通配符就是一种shell实现文件名的扩展,将符合条件的文件列出来,然后再传给命令去处理,若一个条件也不符合,则以普遍参数模式传给命令去使用,就是方便我们查询文件信息。
匹配0个或多个字符
*
]$ ls t* #其实*也可以代表空格 t3 te test1 true.txt
匹配单个字符
?
]$ ls t? t3 te
]$ ls t? #匹配以t为头的两个字符 t3 te t1: #目录的下一层文件也会显示出来 a.tar.gz t t1 t.tar.bz2
匹配[]中的任意单个字符
[tex]
]$ ls t[tex] #只能匹配tt、tx、te这三个文件 te
[!]或[^]:匹配不是中括号字符中的任意单个字符
[!tex]
]$ ls t[!text] t3 t1: #目录下的文件会显示出来 a.tar.gz t t1 t.tar.bz2 ]$ ls t[^ext] #结果和上面相同
[a-x]:匹配中括号中 a到x之间的任意单个字符
[a-t]
]$ ls t[a-t] #匹配t【a到t之间的任意一个字符】 te
{string,string1,string2}: 匹配大括号中任意单个字符串
{e,est,1}
]$ ls t{e,est,1} #匹配不到会有提示 ls: cannot access test: No such file or directory te t1: #目录会全部显示出来 a.tar.gz t t1 t.tar.bz2
元字符
变量相关
=:变量赋值
$
${变量}或$变量
]$ a=10;b=11 ]$ echo $a,${b} 10,11
$()
与``相同,先执行命令,再返回结果
]$ echo $(cat t3) #先执行cat t3命令,然后再返回其结果 this is t3 test
$(())或$[]
只进行整数运算 浮点数会算作为字符串
]$ echo $[(2+4)*3] 18 ]$ echo $(((2+4)*3)) 18
$(())不需要转义重定向 且括号包含以下内容 在$在 [[ ]]中 增加了另一个特性:模式匹配
val++ 后增 val-- 后减 ++val 先增 --val 先减 ! 逻辑求反 ~ 位求反 ** 幂运算 << 左位移 >> 右位移 & 位布尔和 | 位布尔或 && 逻辑和 || 逻辑或
删除变量
unset
]unset liu #删除变量${liu}
重定向相关
> prog > file 将标准输出重定向到文件。 >> prog >> file 将标准输出追加到文件。 < prog < file 从文件file中获取标准输入
逻辑顺序
& 后台运行命令,最大好处是无需等待命令执行结束,就可以在同一命令行下继续输入命令
; 命令结束符。例如p1;p2表示先执行p1,再执行p2
&& 前一个命令执行成功后,才继续执行下个命令。也可以查询当前程序的进程id 例如:p1&&p2,若p1执行成功后,才执行p2,反之,不执行p2
|| 前一个命令执行失败后,才继续执行下一个命令。 例如:p1||p2;若p1执行成功后,不执行p2,反之,才执行p2;
! 否,非,取反
管道符
前一个命令原本要输出到屏幕的数据当作是后一个命令的标准输入,就是前一个命令的输出数据当做是后一个命令的输入数据
|
]$ cat test|grep -i test #搜索test文档中含有test字的行, 并不区分test的大小写
]$ 命令1|命令2|命令3|...
执行范围
()
运用到运算中,使其括号中的优先
{}
范围界定,如 for i in {1..10},变量i取值范围1到10。
配合${}可以在shell编程中引用变量
目录切换
返回根目录(可能不是元字符)
/
]$ ls / #显示根目录信息
返回本用户主目录
~
]$ ls ~ #显示用户主目录信息
返回xx用户主目录
~account
]$ls ~liu #显示账号为liu的主目录信息
放回切换之前的目录
-
]$cd - #返回切换之前的目录
本层目录(可能不是元字符)
.
]$ ls . #显示本地目录信息
上一级目录(可能不是元字符)
..
]$ ls .. #显示上级目录信息
转义符
用来处理输入的特殊数据,就是让通配符和元字符变为普通的字符
反斜杆(\):去除后面通配符或元字符的特殊意义, 使其变成普通的字符
]$ echo this is 5$$ this is 539635 #$$作用是显示当前程序的进程 ID ]$ echo this is 5\$\$ this is 5$$
反引号(``)或$():将里面的命令执行后返回结果
]$ echo $(cat t3) #先执行cat t3命令,然后再返回其结果 this is t3 test ]$ echo `cat t3` this is t3 test
单引号(''):又叫硬转义,其内部所有的shell通配符和元字符变成普通的字符
]$ echo 5'$$' #显示当前程序的进程id 5$$
双引号(" "):又叫软转义,其内部只允许特定的shell元字符: $用于参数代换 `用于命令代替
]$ echo "5$$;`cat t3`" #显示当前程序进程,执行命令 539635;this is t3 test
浮动主题
浮动主题