新建一个脚本的基本流程为
- 新建脚本文件(后缀为sh)
touch script.sh
- 打开并修改脚本文件
open script.sh
oremacs script.sh
- 修改脚本文件的权限(增加可执行权限,
x
代表execute
)chmod +x script.sh
注意事项:
- 脚本是对空格敏感的,如
a="Hello World"
是合法的(声明了一个变量),而a = "Hello World"
是不合法的(等号两边多了一个空格)
注:本文相关代码可以在该链接找到
基础语法
输出一段话
- 利用
echo
向屏幕输出一段话
向控制台输出Hello World ⇓ \dArr ⇓
echo Hello World
变量
- 利用
$
符号引用一个变量
利用一个变量,向控制台输出Hello World ⇓ \dArr ⇓
a="Hello World"
echo $a
变量运算
修改一个变量的值(4种方法) ⇓ \dArr ⇓
let i+=1;
((i++));
i=$[$i+1];
i=$(($i+1))
变量输出格式控制
- 可以通过printf来控制变量输出的格式(如固定5位,多余的补0)
# printf in binary
printf "%05d\n" `echo "obase=2;$var" | bc`
# printf in decimal
printf "%05d" "$var")
将运行结果保存到变量
result=$(<some command>)
可以将命令的运行结果保存到变量result
里面,方便以后使用
# store the result of printf into a variable
cnt=$(ls -al | wc -l);
cnt=$(($cnt+1))
echo $cnt
从命令行读入指令
- 利用
read
指令从命令行读入数据(保存在一个变量内)
从命令行读入一个字符串,并原样输出 ⇓ \dArr ⇓
read input
echo you enter $input
循环(for)
循环向控制台输出 3 个 Hello World ⇓ \dArr ⇓
# format 1
for((i=0;i<3;i++))
do
echo Hello World $i
done
# format 2
for i in {0..3}
do
echo Hello World $i
done
数组
- 利用括号声明一个数组,数组元素之间用空格隔开
- 利用
${list[index]}
访问数组元素
将整个数组输出到命令行 ⇓ \dArr ⇓
story_list=(hello0 hello1 hello2)
for i in {0..3}
do
echo ${story_list[$i]}
done
条件判断(if-else)
基本格式如下
if [ expression 1 ]
then
# command 1
elif [ expression 2 ]
then
# command 2
else
# command 3
fi
例子:读入一个字符,并作出判断 ⇓ \dArr ⇓
echo "do you...?(y/n):"
read readAll
if [[ $readAll = "y" ]]; then
echo "yes"
else
echo "no"
fi
读取文件
cat
指令:以文本形式输出文件内容
逐行读取并输出文件内容 ⇓ \dArr ⇓
cat filename.txt | while read line
do
echo $line
done
写入文件
- 利用
>>
或者>
将命令的结果重定向到文件>>
是在原文件结尾处插入,>
是清除原文件内容然后插入
打开一个文件,写入一个变量和一串字符 ⇓ \dArr ⇓
a="Hello world"
FILE="./filename.txt"
echo $a >> $FILE
echo "----------------------" >> $FILE
简单的运行一个可执行程序
- rand_story 是一个编译好的可执行程序,story.txt,words.txt和3是这个程序接受的三个输入参数
运行程序rand_story ⇓ \dArr ⇓
./rand_story story.txt words.txt 3
将可执行程序的输出写入到文件内
- 注意第一行用的是 ` 而不是单引号 ’
运行程序rand_story,并将程序输出写入到指定文件 ⇓ \dArr ⇓
./rand_story story.txt words.txt 3 >> output.txt
小例子
简易版自动化测试脚本
背景:假设我们现在有一个程序要测试,程序接受三个输入参数,前两个分别是文件名(字符串),第三个是一个数字(数字)
功能:
- 利用循环更改程序输入参数
- 利用循环 + 数组更改字符串类参数
- 将所有结果写入.txt文件
# file name
FILE="./output.txt"
# clear the file content
echo "" > $FILE
echo "-----------test start-----------" >> $FILE
# modify number parameter
for i in {0..30};
do
echo =====testcase $i===== >> $FILE
./rand_story story.txt words.txt $i >> $FILE
done
story_list=(story.txt story1.txt story2.txt)
# modify string parameter
for i in {0..2};
do
echo =====testcase $i===== >> $FILE
./rand_story ${story_list[$i]} words.txt 1 >> $FILE
done
重复执行一个指令,直到成功
背景:有时候我们需要多次执行某一个指令,直到执行成功,如持续ping一个网站直到ping通;当然我们也可以设置一个最大执行次数,避免指令一直失败从而长时间占用资源。同时,我们可以在两次执行之间增加一点延迟。
代码:
cnt=0
until [ "$cnt" -ge 10 ]; do
echo "Hello" && break
cnt=$((cnt + 1))
sleep 1m
done
这里我们使用了一种写法<command 1> && <command 2>
,意思就是当且仅当command 1执行完毕并且返回值为0(成功)的时候,才会执行command 2。
类似的语法还有<command 1> || <command 2>
,意思就是当且仅当command 1执行完毕并且返回值不为0(错误)的时候,才会执行command 2。
应用场景:想要执行多个有依赖关系的指令时会格外有用(如后一个指令要用到前一个指令的结果,如果前一个指令出错则退出程序)。
- 用
&&
来实现的话,就单纯的把所有指令与在一起就好<command 1> && <command 2> && <command 3>
- 用
||
来实现的话,就把每一个指令和exit
或在一起,那么任意一个指令出错的时候,就会执行exit
<command 1> || exit
<command 2> || exit
<command 3> || exit