《Linux Command Line and Shell Scripting Bible》Part 11 构建基本脚本
创建shell脚本 头部放 #! /bin/bash 指定那个shell来运行脚本
要让shell找到脚本:
将shell脚本文件所处的目录添加到PATH环境变量中
再提示符中用绝对或相对路径来引用shell脚本文件。
在这之前需要将shell文件修改为可执行文件 可以用chmod u+x命令
显示消息可以用echo,如果不换行用echo -n
11.4 使用变量
环境变量列表可以通过set命令获取
可以通过 $符来获取这些环境变量。
如果不想转义,可以通过\反斜杠,静止转义
还可以通过${variable}形式引用的变量。变量名两侧额外的花括号通常用来帮助识别美元符后的变量名。
shell脚本,通过$获取变量内容,而且变量名分大小写,如果直接写abc=cba,那cba就回解释成普通的文本字符串
命令替换
反引号``与$(格式)
shijianongdeMBP:~ shijianzhong$ echo $d 2020年 5月21日 星期四 13时55分50秒 CST shijianongdeMBP:~ shijianzhong$ d2=$(date) shijianongdeMBP:~ shijianzhong$ echo $d2 2020年 5月21日 星期四 13时56分05秒 CST shijianongdeMBP:~ shijianzhong$
date的格式化输出
#! /bin/bash today=$(date +%y%m%d) # 格式化日期输出 ls -al /usr/bin > log.$today
11.5重定向输入输出
定向输出 >,追加输出>>
输入重定向 <,输入重定向将文件的内容重定向到命令
还有一种内联输入重定向,用<<
wc << EOF > ni hso > hello > lla > EOF 3 4 17 shijianongdeMBP:part_11 shijianzhong$ who > test1 shijianongdeMBP:part_11 shijianzhong$ time >> test1 real 0m0.000s user 0m0.000s sys 0m0.000s shijianongdeMBP:part_11 shijianzhong$ cat test1 shijianzhong console May 18 11:42 shijianzhong ttys000 May 19 14:54 shijianzhong ttys002 May 21 09:47 shijianzhong ttys004 May 18 16:59 shijianzhong ttys005 May 20 23:43 shijianzhong ttys006 May 21 10:44 shijianongdeMBP:part_11 shijianzhong$ time real 0m0.000s user 0m0.000s sys 0m0.000s shijianongdeMBP:part_11 shijianzhong$ cat test1 shijianzhong console May 18 11:42 shijianzhong ttys000 May 19 14:54 shijianzhong ttys002 May 21 09:47 shijianzhong ttys004 May 18 16:59 shijianzhong ttys005 May 20 23:43 shijianzhong ttys006 May 21 10:44 shijianongdeMBP:part_11 shijianzhong$ date >> test1 shijianongdeMBP:part_11 shijianzhong$ cat test1 shijianzhong console May 18 11:42 shijianzhong ttys000 May 19 14:54 shijianzhong ttys002 May 21 09:47 shijianzhong ttys004 May 18 16:59 shijianzhong ttys005 May 20 23:43 shijianzhong ttys006 May 21 10:44 2020年 5月21日 星期四 14时17分27秒 CST shijianongdeMBP:part_11 shijianzhong$
11.6管道
管道用|,Command1 | Command2 ,Linux系统回同事运行这两个命令,在系统内部将它们连接起来。
在第一命令产生输出的同时,输出会被立即送给第二个命令。数据传输不会用到任何中间文件或缓存区
shijianongdeMBP:part_11 shijianzhong$ ls | sort log.200521 t1143.sh test1
假如一个长列表文件,可以通过ll | more ,分屏显示
11.7执行数学运算
expr命令
shijianongdeMBP:part_11 shijianzhong$ expr 1+2 1+2 shijianongdeMBP:part_11 shijianzhong$ expr 1 + 2 3 shijianongdeMBP:part_11 shijianzhong$ expr 2 * 3 expr: syntax error shijianongdeMBP:part_11 shijianzhong$ expr 2 \* 3 6 shijianongdeMBP:part_11 shijianzhong$
记住里面要有空格,使用*要使用转义字符
shijianongdeMBP:part_11 shijianzhong$ ./t1171 The result 0 shijianongdeMBP:part_11 shijianzhong$ cat t1171 #! /bin/bash var1=10 var2=20 var3=`expr 10 / 20` echo The result $var3 shijianongdeMBP:part_11 shijianzhong$
这样写shell有些麻烦,shell提供了一种更简单的方法来执行数学表达式可以使用$[]来将数学表达式围起来
shijianongdeMBP:part_11 shijianzhong$ var1=$[1 + 2] shijianongdeMBP:part_11 shijianzhong$ echo $var1 3 shijianongdeMBP:part_11 shijianzhong$ var2=$[3 * 2] shijianongdeMBP:part_11 shijianzhong$ echo $var2 6 shijianongdeMBP:part
使用$[]进行数学运算的时候,不用像expr这样对*进行转义,里面的符号,解释器回知道。
shijianongdeMBP:part_11 shijianzhong$ echo $[100 / 45] 2 shijianongdeMBP:part_11 shijianzhong$
bash shell 只支持整数运算
浮点解决方案
shijianongdeMBP:part_11 shijianzhong$ bc -q 2+1 3 1.5*1.5 2.2 scale=5 1.5*1.5 2.25 scale=50 1/3 .33333333333333333333333333333333333333333333333333 scale=0 1/3 0
使用bash内建的计算机bc解决
在bc里面可以设置scale=?,通过?的值来设定有效的小数点保存位数,quit可以退出bc
shijianongdeMBP:part_11 shijianzhong$ bc bc 1.06 Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. var1=2 var2=5 var1/var2 0 scale=5 var1/var2 .40000 quit
在脚本中使用bc
使用命令替换运行bc命令,并将输出赋值给一个变量
variable=$(echo "options; expression" | bc)
shijianongdeMBP:part_11 shijianzhong$ var1=$(echo "scale=5;1/3" | bc) shijianongdeMBP:part_11 shijianzhong$ echo $var1 .33333 shijianongdeMBP:part_11 shijianzhong$
shijianongdeMBP:part_11 shijianzhong$ ./t1173.sh The result is 1252.431 shijianongdeMBP:part_11 shijianzhong$ cat t117 t1171 t1173.sh shijianongdeMBP:part_11 shijianzhong$ cat t1173.sh #! /bin/bash var1=20.1 var2=3.1 var3=`echo "scale=4;$var1 * $var1" | bc` var4=`echo "scale=4;$var3 * $var2" | bc` echo The result is $var4 shijianongdeMBP:part_11 shijianzhong$
涉及大量运算这样回非常不方便,使用内联输入重定向。
variable=$(bc << EOF
options #scale=4,设置小数有效位
staements
expressions
EOF
)
书中案例代码如下:
The final answer for this mess is 2813.9882 shijianongdeMBP:part_11 shijianzhong$ cat test12 #! /bin/bash var1=10.46 var2=43.67 var3=33.2 var4=71 var5=$(bc << EOF scale=4 a1=( $var1 * $var2) b1=( $var3 * $var4) a1 + b1 EOF ) echo The final answer for this mess is $var5 shijianongdeMBP:part_11 shijianzhong$
通过 EOF内联重定向可以参数使用更加方便
11.8退出脚本
可以通过$?查看最后一次退出时候的状态
0 命令成功结束 1 一般性未知错误 2 不适合的shell命令 126 命令不可执行 127 没找到命令 128 无效的退出参数
echo The final answer for this mess is $var5 shijianongdeMBP:part_11 shijianzhong$ date 2020年 5月21日 星期四 15时29分31秒 CST shijianongdeMBP:part_11 shijianzhong$ echo $? 0 shijianongdeMBP:part_11 shijianzhong$ fsdf -bash: fsdf: command not found shijianongdeMBP:part_11 shijianzhong$ echo $? 127 shijianongdeMBP:part_11 shijianzhong$ date +%t shijianongdeMBP:part_11 shijianzhong$ date +%m 05 shijianongdeMBP:part_11 shijianzhong$ date %e date: illegal time format usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format] shijianongdeMBP:part_11 shijianzhong$ echo $? 1 shijianongdeMBP:part_11 shijianzhong$
exit 命令
在shell脚本中,可以改变这种默认行为,返回自己的退出状态码。exit允许你在脚本结束时执行一个退出状态码
shijianzhongdeMacBook-Pro:part_11 shijianzhong$ ./test13.sh The result is 40 shijianzhongdeMacBook-Pro:part_11 shijianzhong$ echo $? 5 shijianzhongdeMacBook-Pro:part_11 shijianzhong$ cat test13.sh #! /bin/bash var1=10 var2=30 var3=$[$var1 + $var2] echo The result is $var3 exit 5 shijianzhongdeMacBook-Pro:part_11 shijianzhong$
也可以在exit 使用变量
shijianzhongdeMacBook-Pro:part_11 shijianzhong$ ./test14 shijianzhongdeMacBook-Pro:part_11 shijianzhong$ echo $? 30 shijianzhongdeMacBook-Pro:part_11 shijianzhong$ cat test14 #!/bin/bash var1=10 var2=20 var3=$[$var1 + $var2] exit $var3 shijianzhongdeMacBook-Pro:part_11 shijianzhong$
状态码要在0~255之间,超过255,就是指定数除以255的余数
小结
shell脚本文件必须定义用于运行脚本的shell。通过#!符号在脚本文件的第一行指定,后面跟上shell的完整路径。
在shell脚本内,你可通过在变量前使用美元符来引用环境变量。也可以定义自己的变量以便于在脚本内使用,并对其赋值,甚至还可以通过反引号或$()捕获某个命令的输出。在脚本中可以通过变量名来获取变量的值
> 定向输出到特定文件, >>追加输出到定向文件,小于号用来将输入重定向到命令,可以将文件内容重定向到莫个命令
Linux管道命令允许你将命令的输出直接重定向到另一个命令的输入。Linux系统能通同事运行这两个命令,将第一个命令的输出发送给第二个命令的输入,不需要借助任何重定向文件。
bash shell提供了多种方式的shell脚本执行数学操作。expr命令进行整数运算的简便方法,如果需要计算浮点运算,可以利用bc计算器命令,将内联数据重定向到输出,然后将输出存储到用户变量
exit 可以输出退出的状态,0表示成功。