bash技巧
-
特殊变量
这个应该非常重要吧,不知道大家的规矩,是很危险的.
$# 传给脚本的参数的个数.
$0 脚本自己的文件的名字.
$1 $2 $3 … $n 这个是脚本的第 n 个参数
$@ 传给脚本的所有参数的列表
$* 以一个字符串数组的方式,显示所有的脚本参数,与位置变量不同,参数可以超过 9 个.
$$ 是脚本运行的但前PID号.
$? 代表最后命令退出状态,0 表示没有错误,这个值就是c语言main函数里最后return 的数值.
-
for循环
-
定量循环
for ((i=1;i<10;i++));do #your code done
-
迭代循环
for i in $(var);do #your code done
-
泛循环
这个名称不大准确,大概意思就是,循环反问变量的意思
for i in 变量1 变量2 变量3;do #不用加$ echo $i done
输出 变量1 变量2 变量3 这样子,这样就可以在for里面循环处理每个变量的东东.
-
-
判断文件加是否存在
if [ ! -d "release" ];then #do somethine you like fi
-d 表示检查后面的字符表示的文件夹是否存在. ! 表示取反
-
判断文件是否存在
if [ -f "test" ];then #do your code fi
可以使用!取反
-
中途强制结束脚本执行
写一个demo如下:
die(){ ret=$? if [ "$ret" != "0" ];then echo "EXECUTE FAIL"; exit $ret; fi } programs1 || die programs2 || die
这样就保证了program1 执行成功后,才会执行program2 .
原理分析.
- bash中,返回0 表示成功, 0 在bash逻辑判断时,被判为 FALSE.
- bash的逻辑判断具有逻辑短路优化, 即:判断 && 时第一为0 提前退出,判断 || 时,第一个为 1 提前退出.
- 在bash中,调用函数不算是执行命令,所以 $? 的值依然不会因为调用函数改变.
- 在bash中 if 也不算是程序,也不影响 $? 的值,但是, [ 算是一个程序,这个程序 判断参数到 ] ,并返回 0,或者 1 ,所以,在上面, $? 的值,要保存一下, 直接 exit $? 的话,一致返回 0 ,因为那是 [ 的返回值.
-
shell中的json字符处理
这个在通过curl做http请求的时候非常有用,因为返回的经常是一个json字符串,使用的工具是 jq (json query);
解析json字符:
cat {json file} | jq 这个就会在控制台以让人可以读的形式进行打印json格式.
查询json内容:
cat {json file} | jq {.key1.key2} 这个就是从 json 的root 开始查找key1,再在key1结构中查找key2,依次类推,以 . 为分割,一层一层的向下找 第一个点必须有,代表root,
-
把字符串分割为数组
-
空格间隔的字符串分割为数组
string="a b c d"; arry=($string) for s in ${arry[@]};do echo $s; done
-
把任意字母分割的数组
原理,也是使用 arr=($var) 的形式进行转换的, arr=($var) 使用一个bash的运行变量 IFS 进行分割,默认这个变量为 ‘ ‘ 空格,只要改变这个变量即可使用我们想要的分割方法进行分割
str="a,b,c,d"; OLD_IFS=$IFS IFS="," #以','分割字符 #也可以使用多个字符作为分割字符比如 # IFS='b,c' 这样的话arr=($str) 后,arr[0]=a, arr[1]=,d arr=($str) IFS=$OLD_IFS
-
-
在bash中读取文件
-
全部读取
content=`cat ‘{file name}’`
-
读取一行处理
#第一种方法 while read line;do echo $line #处理line,line里就是一行 done < '{file name}' #方式二, 貌似这个方式更优雅一些呢 cat '{file name}'|while read line; do echo $line #处理这一行 done #方式三,其实这个不是一行一行的读取,而是分空格读取的,即:一行里有空格后,就按两行看待 for line in `cat {file name}`;do echo $line done
-
-
利用统计数据,绘制统计图表
这个功能主要用于方便的宏观的查看统计数据,数字不是很直观呢,
利用gnuplot绘制图表
gnuplot是一个gnu组织下的一个科学统计出图的软件,功能强大,简单的统计着实有点牛刀杀鸡的感觉.
这个东东出来的东西,利用的数据,是一种以 空格 或者 tab 分割的数据矩阵,并且所有的数据中,不能有空格,空格在这种数据结构中是有特殊意义的
可以利用perl ,bash字符操作等手段,生成这样的数据.
使用,这里主要绘制2d图形
gnuplot -e ‘set term png; set output “{output image path}”; plot “{data file}” using 1:3 with lines; ‘
-e 后面的是gnuplot的命令;直接运行gnuplot会进入互交式界面.
set term png 指示gnuplot以png格式输出.
set output “{output file path}” 指定gnuplot的输出文件路径,gnuplot会生成一个png文件.
plot “{data file}” using 1:3 with lines 以data file的数据绘制图表,使用数据的第1列和第3列绘制,其中,第一个使用的列,被gnuplot默认使用为x轴.第二列将被使用为y轴,如果使用 splot 命令进行3d图形绘制,第三列数据被使用为z轴,with lines 是说把数据文件中的 数据集 以线的形式连接,一个文件中可以有多个数据集,查看 gnuplot使用说明
额外的命令:
set xdata time 设置x轴的数据是时间格式, 默认是数字,使用 set xdata 命令恢复数字模式.
set timefmt “%Y-%m-%d %H:%M%S” 设置时间的格式,
set xlabel “Time” 设置x轴的label. 类似的还有 set ylabel “YValue”; set zlabel “ZValue”
plot|splot 后面跟的with lines 这个就是说绘制图形处理的时候加的附加设置,详细查看 gnuplot使用说明
-
文本处理
-
把多个空格替换为一个,
方式很多,这里介绍sed替换
df | sed 's/ \{1,\}/ /g'
使用s命令进行替换, sed手册 后面的正则:{} 表示从几个到几个,没有的参数自适应(无限多) {还需要转意, {1,}就是至少一个,至多不限制的意思, perl中,和vim中的正则会略有变化, vim中,使用* 表示前一个字符重复一次或多次, perl中,使用 + 表示前面一个或多个.
-
-
数组的操作
#按照索引值取内容 a="${array_name[index]}" #取所有数组的内容,一般用于循环和数组转化为字符串 all="${array_name[@]}" #切片start开始,数number个,numbers不写表示取剩下的全部 slice="${array_name[@]:start:number}"
-
字符串的操作
#切片 和数组差不多, #看来shell默认如果有空格就按空格树index,没有就一个字符一个字符数index slice="{var:start:number}" #去右侧,也就是最后几个字符 last="${var:-length}" # 有关#和% #是删去左边的字符(包括指定字符),查找顺序是从左往右,#便是找第一个,##找最后一个. %是删去右边的字符(包括指定字符),查找顺序是从右到左,%是第一个,%%是最后一个. #*{word} 表示删去第一个word左边的字符, %{word}* 表示删去第一个word右边的字符.