本文转自shell 脚本里的 特殊字符 \$(( ))、\$( )、` `与\${ }的区别——马克图
在 bash 中,$( )与` `(反引号)都是用来作命令替换的
命令替换与变量替换差不多,都是用来重组命令行的,先完成引号里的命令行,然后将其结果替换出来,再重组成新的命令行
\$( )与` `
在操作上,这两者都是达到相应的效果,但是建议使用\$( ),理由如下:
` `很容易与’ '搞混乱,尤其对初学者来说,而\$( )比较直观
最后,\$( )的弊端是,并不是所有的类 unix 系统都支持这种方式,但反引号是肯定支持的。
关于命令嵌套:
1 | (ps -ef|grep `ps -ef|grep nginx |grep 'ottcache'|grep 'master process'|awk '{print $2}' ` |grep 'worker process'|awk '{print $2}') |
里面的命令用 ` ` 反引号得出 pid , 再替换掉该位置,$( ) 执行另一个命令。
1 | echo today is $(date "+%Y-%m-%d") |
${ }变量替换
一般情况下,\$var与\${var}是没有区别的,但是用${ }会比较精确的界定变量名称的范围
1 | A=Linux |
截取变量的部分
1 | file=/dir1/dir2/dir3/my.file.txt |
可以用${}分别替换得到不同的值:
命令 | 解释 | 结果 |
---|---|---|
${file#*/} | 删掉第一个 / 及其左边的字符串 | dir1/dir2/dir3/my.file.txt |
${file##*/} | 删掉最后一个 / 及其左边的字符串 | my.file.txt |
${file#*.} | 删掉第一个 . 及其左边的字符串 | file.txt |
${file##*.} | 删掉最后一个 . 及其左边的字符串 | txt |
${file%/*} | 删掉最后一个 / 及其右边的字符串 | /dir1/dir2/dir3 |
${file%%/*} | 删掉第一个 / 及其右边的字符串 | (空值) |
${file%.*} | 删掉最后一个 . 及其右边的字符串 | /dir1/dir2/dir3/my.file |
${file%%.*} | 删掉第一个 . 及其右边的字符串 | /dir1/dir2/dir3/my |
记忆的方法为:
# 是去掉左边(键盘上 # 在 \$ 的左边)
% 是去掉右边(键盘上 % 在 $ 的右边)
一个符号是最小匹配;两个符号是最大匹配
取子串及替换
命令 | 解释 | 结果 |
---|---|---|
${file:0:5} | 提取最左边的5个字节 | /dir1 |
${file:5:5} | 提取第5个字节右边的连续5个字节 | /dir2 |
${file/dir/path} | 将第一个dir提换为path | /path1/dir2/dir3/my.file.txt |
${file//dir/path} | 将全部dir提换为path | /path1/path2/path3/my.file.txt |
${#file} | 获取变量长度 | 27 |
$(( ))可以整数运算、进制转换、重定义变量值
bash中整数运算符号
符号 | 功能 |
---|---|
+ - * / | 分别为加、减、乘、除 |
% | 余数运算 |
& | ^ ! | 分别为AND、OR、XOR、NOT |
e.g
1 | echo $((2*3)) |
$(( ))可以将其他进制转成十进制数显示出来
用法如下:
echo $((N#xx))
其中,N为进制,xx为该进制下某个数值,命令执行后可以得到该进制数转成十进制后的值。
1 | echo $((2#110)) |
(( ))重定义变量值,是 [ ] 数学表达式的加强版
1 | a=5;b=7 |
\${name[*]} \${name[@]} ${#name[*]} 区别
在 linux 的 shell 里,${name}可以表示变量,也可以表示数组。
name后面加[ ]的,一般是数组。
命令 | 解释 |
---|---|
${name[*]} | 数组所有元素(all of the elements) |
${name[@]} | 数组每一个元素(each of the elements),循环数组用这个 |
\${#name[*]} | 数组元素的个数,也可以写成 \${#name[@]} |
\${name:-Hello} | 如果\${name}没有赋值,那么它等于Hello,如果赋值了,就保持原值,不用管问这个Hello了 |
\${!array_name[@]}、\${!array_name[*]} | 获取数组下标 |
1 | str="114.114.114.114 2000:192:434:234" |
单小括号 ()
命令组。括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用。括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格。
命令替换。等同于`cmd`,shell扫描一遍命令行,发现了\$(cmd)结构,便将\$(cmd)中的cmd执行一次,得到其标准输出,再将此输出放到原来命令。有些shell不支持,如tcsh。
用于初始化数组。如:array=(a b c d)
($str) 会把字符串按照字段分隔符:空格、制表符、换行符,分割形成数组
注意:[[ ]] 是字符串表达式的加强版