脚本是什么?
脚本是一堆命令的集合,类似于程序,但不需要编译,即可逐行执行从而完成批量工作,具有以下特点:
- 使用 # 作为注释,文件后缀为.sh
- 读到 enter 就开始执行该行命令,若需换行应使用 \ 转义enter
- 执行的脚本文件需要有 rx 权限
- 命令用 $() 括起来,算术运算用 $(())括起来
脚本执行方式
- 可使用绝对路径 /home/xxx/xxx.sh 或在相对路径下 ./xxx.sh 执行
- 可用命令 bash xxx.sh 或 sh xxx.sh 执行
- 可将脚本文件放在PATH指定的目录或将脚本文件所在目录添加到PATH,然后就可通过文件名直接执行
上述3种方式都会使用一个新的bash环境执行脚本,即该脚本在子程序的bash内执行,故当子程序执行完成后,其内的变量在结束时不会传回给父程序,如下变量name在脚本执行完后就不存在了

- 而使用 source xxx.sh 执行脚本,可保留变量

符号判断
如 test -e filename && echo “exist” || echo “Not exist” 可测试filename是否存在
| 符号 | 意义(文件类型) |
|---|---|
| -e | 文件是否存在 |
| -f | 是否为文件 |
| -d | 是否为目录 |
| -b | 是否为block设备(如硬盘) |
| -c | 是否为character设备(如鼠标) |
| -S | 是否为Socket文件 |
| -p | 是否为pipe文件 |
| -l | 是否为链接文件 |
如 test -r filename 可测试filename是否可读
| 符号 | 意义(文件属性) |
|---|---|
| -r | 是否可读 |
| -w | 是否可写 |
| -x | 是否可执行 |
| -u | 是否有SUID |
| -g | 是否有SGID |
| -k | 是否有Sticky bit |
| -s | 是否为空白文件 |
如 test file1 -nt file2 可测试file1是否比file2新
| 符号 | 意义(文件比较) |
|---|---|
| -nt | 是否更新 |
| -ot | 是否更旧 |
| -ef | 是否同一文件 |
如 test n1 -eq n2 可测试n1是否等于n2
| 符号 | 意义(数字比较) |
|---|---|
| -eq | 相等 |
| -ne | 不等 |
| -gt | 大于 |
| -lt | 小于 |
| -ge | 大于等于 |
| -le | 小于等于 |
如 test -z string 可测试string是否为空
| 符号 | 意义(字符串) |
|---|---|
| -z | 是否为空 |
| -n | 是否非空 |
| == / != | 是否等于/不等 |
如 test -n str1 -a -n str2 可测试str1和str2是否为空
| 符号 | 意义(多重条件) |
|---|---|
| -a | 与 |
| -o | 或 |
| ! | 非 |
符号 []
利用 [] 可实现与test一样的效果,但在其内的表达式两端需要有空白字符分隔,如
[ "song" == "son" ] && echo "equal" || echo "not equal"
[ -e "temp" ] && echo "exist" || echo "Not exist"
此外,[] 中的变量需要用""括起来,否则对于如下判断会变成 song zai == “song” 报错

故正确的方式为 [ “${name}”==“song” ]
脚本的参数及偏移
在运行脚本文件 xxx.sh 时可在其后面加上参数,$0代表当前脚本文件名,$1$2…后即为传入的参数,此外还有一些特别参数
| 符号 | 意义 |
|---|---|
| $# | 表示传入参数的个数 |
| $@ | 表示所有传入的参数(用空白分割) |
示例1——test.sh 代码如下
echo "File name = ${0}"
echo "Parameter number = $#"
echo "Parameter = $@"
echo "1st parameter = ${1}"
运行test.sh 并传入2个参数

示例2——利用 shift 可对传入的参数进行偏移(默认偏移一位),test.sh 代码如下
echo "Parameter number = $#"
echo "Parameters = $@"
echo "1st parameter = ${1}"
shift 2
echo "1st parameter = ${1}"
运行 test.sh 并传入4个参数,可看到一开始 $1=one,shift 2后$1=three

条件判断
if
- 先判断条件1,当条件1成立时执行命令1
- 条件1不成立,然后判断条件2,当条件2成立时执行命令2
- 若全部条件都不成立,执行命令3
if [ condition1 ]; then
command1
elif [ condition2 ]; then
command2
...
else
command3
fi
case
- 先判断变量var是否等于str1,若等于执行命令1
- 若不等于,然后判断变量var是否等于str2,若等于执行命令2
- 若全部str都不等于,执行命令3
case $var in
"str1")
command1
;;
"str2")
command2
;;
...
*)
command3
;;
esac
循环判断
while
while当条件成立时进入循环,直到条件不成立才退出循环
while [ conditiion ]
do
command
done
until
until 当条件成立时才终止循环,否则进入循环
until [ conditiion ]
do
command
done
for
- 第一次循环时,var=str1,执行命令
- 第二次循环时,var=str2,执行命令…
for var in str1 str2...
do
command
done
下面的for和大多数程序语言一样
for ((initial;condition;step))
do
command
done
示例——for.sh代码如下,连续打印1-5,seq代表后面的两个数值是一直连续的,此外还可用{1. .5}
for num in $(seq 1 5)
do
echo ${num}
done
函数
函数可整合相同的命令,以减少代码的冗余
function methodname(){
command
}
func.sh代码如下,print()函数的${1}来自调用时传递的参数
function print(){
echo "your input is ${1}"
}
read -p "input num:" num
num=$((${num}%2))
case ${num} in
"0")
print odd
;;
"1")
print even
;;
*)
print illegal
;;
esac
上面代码运行如下

Debug
命令 sh 不仅可用于执行脚本文件,还可用于debug,-n不执行脚本仅查询语法错误,-v执行前先将脚本内容输出到屏幕,-x将执行过程显示到屏幕

例子
利用date建立文件
先利用read读取输入,判断输入是否为空,生成变量并创建文件
read -p "Please input your filename: " input
filename=${input:-"noinput"}
date=$(date +%Y%m%d)
file=${filename}${date}
touch ${file}
运行结果如图

830

被折叠的 条评论
为什么被折叠?



