shell编程总结
引用变量
$@ 与 $* 都是代表作用范围内的所有引用变量,不过她们两者有一个不同点。
$* : 将所有的引用变量视为一个整体。
$@ : 则仍旧保留每个引用变量的区段观念,使用时候加引号。
$? : $?环境变量表示上一次命令的返回结果,0表示成功,非0表示失败
$0 : 脚本名;
$1-$9: 传入的第1到第9个参数;
$# : 传递到脚本的参数总数;
$$ : 脚本运行后的当前进程ID;
单个()
- 指令群组, 用()将一串连续指令括起来, 指令群组有一个特性,shell会以产生 subshell 来执行这组指令。因此,在其中所定义的变数,仅作用于指令群组本身。
如下面的例子:(cd ~ ; vcgh=pwd
;echo $vcgh) - 命令替换。等同于
cmd
.
shell扫描一遍命令行,发现了 ( c m d ) 结 构 , 便 将 (cmd)结构,便将 (cmd)结构,便将(cmd)中的cmd执行一次,得到其标准输出,再将此输出放到原来命令。有些shell不支持,如tcsh。 - 用于初始化数组。如:array=(a b c d)
双(())
- 逻辑运算, 用于比较数字, 且不用转义, 可用普通的>或<, 扩展了for,while,if条件测试运算
if ((8>7&&5==5)); then echo “true”; echo “false”; fi
for ((i=0;i<30;i++)); do curl localhost:8080; sleep 1; done
i=0;while ((i<3)); do ((i++)); echo “xxx”; sleep 1; done - 也可以用于数字计算, 计算的时候运算符与数字之间不能有空格,例如: sum=
(
(
((
((sum+4))
( ( e x p ) ) : 计 算 数 学 表 达 式 e x p 的 数 值 , 其 中 e x p 只 要 符 合 C 语 言 的 运 算 规 则 即 可 , 甚 至 三 目 运 算 符 和 逻 辑 表 达 式 都 可 以 计 算 , 输 出 结 果 自 动 转 为 十 进 制 。 另 外 也 可 以 用 ‘ e x p ‘ 计 算 e x p 的 值 . l e t , e x p r 等 命 令 完 成 a = 1 ; b = 2 ; c = 5 ; a = ((exp)): 计算数学表达式exp的数值, 其中exp只要符合C语言的运算规则即可, 甚至三目运算符和逻辑表达式都可以计算, 输出结果自动转为十进制。 另外也可以用 `exp` 计算exp的值. let,expr等命令完成 a=1;b=2;c=5;a= ((exp)):计算数学表达式exp的数值,其中exp只要符合C语言的运算规则即可,甚至三目运算符和逻辑表达式都可以计算,输出结果自动转为十进制。另外也可以用‘exp‘计算exp的值.let,expr等命令完成a=1;b=2;c=5;a=((a+1,b++,c++)); echo a , a, a,b,$c --结果: 5,3,6 - 单纯用 (( )) 也可重定义变量值. 比如: a=5; ((a++))
单个[ ]
- bash 的内部命令, [和test是等同的.
- Test和[]中可用的比较运算符只有=和!=,两者都是用于字符串比较的,不可用于整数比较,整数比较只能使用-eq,-gt这种形式. 无论是字符串比较还是整数比较都不支持大于号(>),小于号(<) .
- []中的逻辑与和逻辑或使用-a 和-o 表示。且[]前后都有空格.
双[[ ]]
- [[是 bash 程序语言的关键字。并不是一个命令,[[ ]] 结构比[ ]结构更加通用. bash把[[ ]]中的表达式看作一个单独的元素,并返回一个退出状态码.
- 在[[和]]之间所有的字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换.
- 支持字符串的模式匹配, 字符串比较时可以把右边的作为一个模式(而不仅仅是一个字符串), 比如[[ hello == hell? ]]. 使用=~操作符时甚至支持shell的正则表达式.
- 使用[[ … ]]条件判断结构,而不是[ … ],能够防止脚本中的许多逻辑错误。
比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错。比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果不适用双括号, 则为if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]。
大括号{}
- 大括号拓展
第一种:对大括号中的以逗号分割的文件列表进行拓展。如 touch {a,b}.txt 结果为a.txt b.txt
第二种:对大括号中以点点(…)分割的顺序文件列表起拓展作用,如:touch {a…d}.txt 结果为a.txt b.txt c.txt d.txt - 替换
v a r : ? s t r i n g : 若 变 量 v a r 为 空 , 则 把 s t r i n g 输 出 到 标 准 错 误 中 , 并 从 脚 本 中 退 出 ; 若 变 量 v a r 不 为 空 , 则 用 变 量 v a r 的 值 来 替 换 {var:?string} : 若变量var为空,则把string输出到标准错误中,并从脚本中退出; 若变量var不为空,则用变量var的值来替换 var:?string:若变量var为空,则把string输出到标准错误中,并从脚本中退出;若变量var不为空,则用变量var的值来替换{var:?string}. 可利用此特性来检查是否设置了变量的值.
v a r : − s t r i n g : 若 变 量 v a r 为 空 , 则 用 命 令 行 中 的 s t r i n g 来 替 换 {var:-string} : 若变量var为空,则用命令行中的string来替换 var:−string:若变量var为空,则用命令行中的string来替换{var:-string}; 否则变量var不为空时,则用变量var的值来替换${var:-string}.
v a r : = s t r i n g : 若 变 量 v a r 为 空 , 则 用 命 令 行 中 的 s t r i n g 替 换 {var:=string} : 若变量var为空,则用命令行中的string替换 var:=string:若变量var为空,则用命令行中的string替换{var:=string}, 同时把string赋给变量var; 否则变量var不为空时,则用变量var的值来替换${var:=string}. 可用于判断某个变量是否赋值,没有的话则给它赋上一个默认值.
${var:+string} : 替换规则和上面的相反. 若var为空时则不替换或者说是替换成变量var的值, 只有当var不是空的时候才替换成string.
补充扩展:在上面这四种替换结构中string不一定是常值的,可用另外一个变量的值或是一种命令的输出. - 字符串截取
${var#pattern} : shell在variable中查找, 看是否以给定的pattern模式 开始, 如果是,则把variable中的内容 去掉 左边最短 的匹配模式.
${var##pattern}: shell在variable中查找, 看是否以给定的pattern模式 开始, 如果是,则把variable中的内容 去掉 左边最长 的匹配模式.
${var%pattern} : shell在variable中查找, 看是否以给定的pattern模式 结尾, 如果是,则把variable中的内容 去掉 右边最短 的匹配模式.
KaTeX parse error: Expected '}', got '#' at position 107: …充扩展: 模式匹配记忆方法: #̲ 是去掉左边(在键盘上#在之左边)
% 是去掉右边(在键盘上%在$之右边)
#和%中的单一符号是最小匹配,两个相同符号是最大匹配。
这四种模式中都不会改变variable的值, 结构中的pattern支持通配符,*表示零个或多个任意字符,?表示仅与一个任意字符匹配,[…]表示匹配中括号里面的字符,[!..]表示不匹配中括号里面的字符。 - 字符串提取和替换
v a r : n u m 1 : n u m 2 : n u m 1 是 位 置 , n u m 2 是 长 度 。 表 示 从 {var:num1:num2} : num1是位置,num2是长度。表示从 var:num1:num2:num1是位置,num2是长度。表示从var字符串的第 n u m 1 个 位 置 开 始 提 取 长 度 为 num1个位置开始提取长度为 num1个位置开始提取长度为num2的子串。不能为负数。
${var/pattern/pattern} : 表示将var字符串的第一个匹配的pattern替换为另一个pattern.
${var//pattern/pattern}: 表示将var字符串的所有能匹配的pattern都替换为另一个pattern. - 在$后, 表示取变量的值
${param}
多条命令顺序执行
- 单小括号 (cmd1;cmd2;cmd3) 新开一个子shell顺序执行命令cmd1,cmd2,cmd3, 各命令之间用分号隔开, 最后一个命令后可以没有分号。
- 单大括号 { cmd1;cmd2;cmd3;} 在当前shell顺序执行命令cmd1,cmd2,cmd3, 各命令之间用分号隔开, 最后一个命令后必须有分号, 第一条命令和左括号之间必须用空格隔开。
补充扩展: 对{}和()而言, 括号中的重定向符只影响该条命令, 而括号外的重定向符影响到括号中的所有命令.
多条命令有选择的执行: (&& 、 ||)
1)&&
&&表示如果前面的命令执行结果(不是表示终端输出的内容,而是表示命令执行状态的结果)返回0则执行后面的,否则不执行,你可以从KaTeX parse error: Expected 'EOF', got '&' at position 32: …果; 2)|| ||实现与&̲&相反的控制效果,当上一条命令…?≠0)时,则执行它后面的命令;
时间处理脚本
date +%s
1575011244
date +%s -d “2019-11-29 15:07:24”
1575011244
date “+%Y-%m-%d %H:%M:%S”
2019-11-29 15:13:05
date “+%Y-%m-%d %H:%M:%S” -d @1575011244
2019-11-29 15:07:24
md5sum的坑
echo -n “” | md5sum — 正确
echo “” | md5sum — 错误,默认会对字符串加结尾符
常用语法记录
1) for循环语句:
for (( i = 0; i < ${TABLE_NUMS}; i++ )); do
done
2) if 语句:
if [ -n ${click_id} ]; then # 不为空
echo $click_id
return
fi
例如:
if [ $1x == "ab"x ]; then
echo “you had enter ab”
elif [ $1x == "cd"x ]; then
echo “you had enter cd”
else
echo “you had enter unexpected word”
fi