shell_02

来源:互联网 发布:全国最好的专科 知乎 编辑:程序博客网 时间:2024/05/02 04:47
算术操作(expr) --在bash中只能做整数的运算
+ 加
- 减
* 乘
/ 除(取整)
% 取余


$(())
$[]


expr 60 \* 60 \* 24
expr 60 \* 60 \* 7
expr 1 + 1
expr 1 * 1
expr $( 10 + 10 ) / 10
expr  $((10 + 10))  / 10
expr  10 % 3


# expr  $RANDOM % 10  


# let "v=2**16"
# echo $v
65536   


退出状态


在Linux系统中,每当命令执行完成后,系统都会返回一个退出状态。该退出状态用一整数值表示,用于判断命令运行正确与否。
若退出状态值为0,表示命令运行成功
若退出状态值不为0时,则表示命令运行失败
最后一次执行的命令的退出状态值被保存在内置变量“$?”中,所以可以通过echo语句进行测试命令是否运行成功
0 表示运行成功,程序执行未遇到任何问题
1~125 表示运行失败,脚本命令、系统命令错误或参数传递错误
126 找到了该命令但无法执行
>128 命令被系统强制结束






条件表达式:
test命令
用途:测试特定的表达式是否成立,当条件成立时,命令执行后的返回值$?为0,否则为其他数值
格式:     test  条件表达式
              [   条件表达式   ]


test可以测试表示有哪些:
1、文件状态
2、字符串的比对
3、整数的比对
4、多条件组合(|| && !)(-a -o !)


------------------------------------------------------
#man test     
-a  = &&     -o = ||   !


单个条件:   [ ! 1 -eq 1 ]   两个值的结果再取反 ,感叹号的优先级别最低,除非加括号;
! [ 1 -eq 1 ]


多个条件:
[ 1 -eq 1 -a 10 -eq 10 ]   =  [ 1 -eq 1 ] && [ 10 -eq 10 ]  两个条件成立,才正确;


[ 1 -eq 1 -o 10 -eq 10 ]    = [ 1 -eq 1 ] || [ 10 -eq 10 ] 取或; 


[ 1 -eq 1 -o 10 -eq 10 -o 1 -eq 1 ]    = [ 1 -eq 1 ] || [ 10 -eq 10 ]  ||  [ 1 -eq 1 ]
-----------------------------------------------------
# test 1 = 1
# echo $?
0


# [ 1 = 1 ]                        --[] = test      --单条件
# echo $?
0


# [ 1 = 1 ] && echo YES
YES


# [ 1 = 2 ] && echo YES --无返回


|| -o or
&& -a and
!


条件的组合:




[ 1 = 1 -a 1 = 2 ] 与组合


[ 1 = 1 ] && [ 1 = 2 ] 与组合


[ 1 = 1 ] || [ 1 = 2 ] 或组合


[ 1 = 1 -o  1 = 2 ]         或组合
逻辑运算符
1)
逻辑运算符主要包括逻辑非、逻辑与、逻辑或运算符,具体描述如下表所示:
逻辑操作符 描述 
!expression    如果expression为假,则测试结果为真
expression1 a expression2 如果expression1和expression同时为真,则测试结果为真
expression1 o expression2 如果expression1和expression2中有一个为真,则测试条件为真


2)
下表是逻辑运算符的“真假表”,其中expr1和expr2为表达式,用于描述了一个测试条件。
expr1  expr2   !expr1  ! expr2  expr1 a expr2  expr1 o expr2 
 真    真   假       真真 
 真    假   真       假真  
 假    真   假       假真 
 假    假    真       假假 




[ ! 1 -eq 1 ]    尽量用 -eq 不用 =  ;  -eq 当整数处理; = 当字符串处理;shell的内部处理;
<字符串或串(String)是由数字、字母、下划线组成的一串字符。一般记为 s=“a1a2···an”(n>=0)。它是编程语言中表示文本的数据类型。>


常见的表达式类型
1、测试文件状态
2、字符串比较
3、整数值比较
4、逻辑测试




文件表达式:
       -a file
              文件是否存在
# [ -a /etc ] && echo YES --目录
YES


# [ -a /etc/passwd ] && echo YES --文件
YES


# [ -a /etc/passwdddd ] && echo YES --无返回值


-------------------------------------
       -b file
              文件存在,而且是设备文件
# [ -b /dev/sda ] && echo YES
YES


# [ -b /dev/passwd ] && echo YES --无返回值


-------------------------------------
       -c file
              文件存在,而且字符文件
# [ -c /dev/tty1 ] && echo YES
YES


# [ -c /etc/passwd ] && echo YES --无返回值


-------------------------------------
       -d file
              文件存在,而且类型是目录
# [ -d /etc/ ] && echo YES
YES


# [ -d /etc/passwd ] && echo YES --无返回值
-------------------------------------
       -e file
              文件的真实文件是否存在。
-------------------------------------
       -f file
              文件存在,而且常规文件
# [ -f /etc/passwd ] && echo YES
YES


# [ -f /etc/ ] && echo YES --无返回值
-------------------------------------
       -g file
              文件存在,而且设置强制位


# find / -perm -2000 --查找系统中哪些文件拥有强制位
# [ -g /usr/bin/wall ] && echo YES
YES
# [ -g /usr/bin/vim ] && echo YES --无返回值




-------------------------------------
       -h file
              文件存在,而且是软链接文件
-------------------------------------
       -k file
              拥有粘滞位目录
[ -k /tmp ] && echo YES
YES


# [ -k /root ] && echo YES --无返回值


-------------------------------------
       -p file
              测试管道文件


# find / -type p --查找系统中有哪些管道文件
# [ -p /tmp/vmware-root.2 ] && echo YES
YES
# [ -p /etc/passwd ] && echo YES --无返回值


-------------------------------------
       -r file
              文件存在,而且当前用户对此拥有读的权限
# su - user01 --切换到普通用户
$ [ -r /etc/passwd ] && echo YES
YES


$ [ -r /etc/shadow ] && echo YES --无返回值


------------------------------------- 
       -s file
              文件存在,而且文件内容非空
# touch /opt/a.txt
# [ -s /opt/a.txt ] && echo YES --无返回值


# [ -s /etc/passwd ] && echo YES
YES


-------------------------------------
       -t 文件描述符(FD)是在一个终端打开的
-------------------------------------
       -u file
              拥有suid的文件
# find / -perm -4000
# [ -u /bin/mount ] && echo YES
YES


# [ -u /etc/passwd ] && echo YES --无返回值


-------------------------------------
       -w file
              测试文件写权限
# [ -w /etc/passwd ] && echo YES
YES
# [ -w /etc/ ] && echo YES
YES


$ [ -w /etc/passwd ] && echo YES --无返回值
-------------------------------------
       -x file
              测试是否拥有执行权限
$ [ -x /bin/ls ] && echo YES
YES


$ [ -x /sbin/unix_update ] && echo YES --无返回值


-------------------------------------
下面为大写字母:
-------------------------------------
       -O file
              测试文件拥有者是否是当前用户
$ touch /tmp/a
$ [ -O /tmp/a ] && echo YES
YES


$ [ -O /etc/passwd ] && echo YES --无返回值


-------------------------------------
       -G file
              对此文件属组(主组)
$ touch /tmp/a
$ [ -G /tmp/a ] && echo YES
YES


$ [ -G /etc/passwd ] && echo YES --无返回值


-------------------------------------
       -L file
              True if file exists and is a symbolic link.    --文件存在而且是软链接
-------------------------------------
       -S file
              测试对象是否是socket
# [ -S /dev/log ] && echo YES
YES


# [ -S /etc/passwd ] && echo YES --无返回值
-------------------------------------
       -N file
              测试文件最后一次至今有无更改过


# [ -N /etc/passwd ] && echo YES --无返回值


# useradd a
# [ -N /etc/passwd ] && echo YES
YES
-------------------------------------
       file1 -nt file2 --file1是否比file2新       -n  比较哪个文件新(和t在一起)
              True if file1 is newer (according to odification date) than file2, or if file1 exists and file2 does not.
# [ /etc/passwd -nt /var/log/messages ] && echo YES




# [ /var/log/messages -nt /etc/passwd ] && echo YES
YES


-------------------------------------
       file1 -ot file2 --测试filt1是否老于file2
              True if file1 is older than file2, or if file2 exists and file1 does not.
# [ /var/log/messages -ot /etc/passwd ] && echo YES
YES




-------------------------------------
       file1 -ef file2
              True if file1 and file2 refer to the same device and inode numbers.


# [ /etc/init.d -ef /etc/rc.d/init.d ] && echo YES --可以用于测试两个文件是否是硬链接的关系
YES


-------------------------------------


字符串表达式:


       -z string
              字符串true,如果字符串是空的。
# [ -z '' ] && echo YES
YES


# [ -z 'aa' ] && echo YES --无返回值


-----------------
       string
       -n string
              字符串true,如果字符串不为空。
# [ -n 'aa' ] && echo YES
YES


# [ -n '' ] && echo YES --无返回值
-----------------
       string1 == string2
              True if the strings are equal.  = may be used in place of == for strict POSIX compliance.
# [ 'aa' == 'aa' ] && echo YES
YES


# [ 'aa' == 'ab' ] && echo YES


-----------------
       string1 != string2
              True if the strings are not equal.
# [ 'aa' != 'ab' ] && echo YES
YES


# [ 'aa' != 'aa' ] && echo YES --无返回值


-----------------
       string1 < string2
              True if string1 sorts before string2 lexicographically in the current locale.
# [ aa \< aaa ] && echo YES
YES


# [ aaa \< ccc ] && echo YES
YES




       string1 > string2
              True if string1 sorts after string2 lexicographically in the current locale.






整数对比表达式:
arg1 OP arg2
-eq equal等于
-ne not equal不等于
-lt    lesser than小于
-le    lesser equal小于等于
-gt granter then大于
-ge granter equal大于等于

# [ 1 -eq 1 ] && echo YES
YES
# [ 1 -eq 2 ] && echo YES


# [ 1 -ne 2 ] && echo YES
YES


# [ 1 -lt 2 ] && echo YES
YES


# [ 2 -gt 1 ] && echo YES
YES


# [ 1 -le 1 ] && echo YES
YES
# [ 1 -le 2 ] && echo YES
YES


# [ 2 -ge 2 ] && echo YES
YES
# [ 3 -ge 2 ] && echo YES
YES


表达式的逻辑组合:
1、&& -a逻辑与
2、|| -o逻辑或
3、! 逻辑非

[ 1 -gt 2 ] -a [ -f /etc/passwd ]
[ 1 -gt 2 ] && [ -f /etc/passwd ]


或:
[ 1 -gt 2 ] -o [ -f /etc/passwd ]
[ 1 -gt 2 ] || [ -f /etc/passwd ]


非:
[ 1 -gt 2 ] -a [ ! -f /etc/passwd ]


总结:
1、判断文件类型
-f
-O -u -L -h -nt -ot -k -s -S
test -f /etc/passwd
[ -f /etc/passwd ]


2、字符串
-z -n
==
!=
>=
<=


3、整数
-eq -gt -ge -lt -le




结构化语句:
if for while until case function




--------------------------------------------
If 语句 --用于判断一个点
       if list; then list; [ elif list; then list; ] ... [ else list; ] fi
              The if list is executed.  If its exit status is zero,  the  then
              list  is  executed.   Otherwise,  each  elif list is executed in
              turn, and if its exit status is  zero,  the  corresponding  then
              list is executed and the command completes.  Otherwise, the else
              list is executed, if present.  The exit status is the exit  sta-
              tus of the last command executed, or zero if no condition tested
              true.






if
单分支
if [  ] ...
then
command01 ...
fi
双分支
if [  ]
then
command01
else
command01
fi


for --循环结构化语句(一般是给定区间或者范围来取值)
格式1:
for name [ in word ] ; do list ; done

格式2:
for (( expr1 ; expr2 ; expr3 )) ; do list ; done






for i in 1 2 3 
do
echo $i
done

for i in {1..10}
do
echo $i
done

for ((i=1;i<=10;i++))
do
echo $i
done









while --当条件成立的时候循环
while :
do
echo hello
done




until --当条件不成立的时候循环
until []
do
echo hello
done


continue/break






while --当条件成立时循环
while [ 1 = 1 ]
do
echo "i love you forever"
done

# while : ; do echo 'i love you forever!!!'; sleep 3s  ;done

# while true ; do echo 'i love you forever!!!'; sleep 3s  ;done


while的另一种模式:
# vim a.txt
123
abc
456


while read line
do
echo $line
done<a.txt




cat a.txt | while read line;do echo $line; done





until --当条件不成立的时候循环
until [ 1 != 1 ]
do
command1
command2
done


break --做循环时如果满足条件强制可以跳出循环,此时循环结束
continue --满足条件时也可以跳出循环,但可以循环下一个元素。








case --分支判断语句(可以判断一个面(区间))


case $1 in
case1)
command01
;;
case2)
command02
;;
case3)
command03
.....
*)
esac 


函数
1、在编写Shell脚本程序时,将一些需要重复使用的命令操作,定义为公共使用的语句块,即可称为函数
2、合理使用Shell函数,可以使脚本内容更加简洁,增强程序的易读性,提高执行效率


function_name() {
command1
command2
}

function_name --调用函数


function function_name() {

}








显示选择菜单:
select name in [ a b c ]
do


done




--------------------------------------------
汉字属于字符串  用字符串的格式  
#sh -n xxx.sh   检查语法
#sh -x xxx.sh   调试模式


-------------------------------------------


• bash shell 调试方法


• 打开调试模式
• $set -x
• $bash -x shell.sh


• 关闭调试模式
• $set +x


sh -n test.sh --检查语法(结构化语句的语法)
sh -x test.sh --调试








如果参数过太多,出现这个报错:too many arguments,需要使用xargs
xargs                (1)  - build and execute command lines from standard input


# awk -F: '{print $1}' /etc/passwd | xargs -i mkdir -p {}