shell - 注释
单行注释使用:#。
多行注释:在被注释的内容端加上: <<<EOF 被注释的内容 EOF 或者 <<! 被注释的内容 !。
shell - 变量、大括号{}、小括号()
在shell脚本中,使用变量时可以不加大括号($变量名),但是最好加上(${变量名})。
示例:使用变量名
测试脚本文件test.sh内容如下:
#!/bin/bash
VAR="hello"
echo "line1: $VAR"
echo "line2: $VARlinuxbar"
echo "line3: ${VAR}"
echo "line4: ${VAR}linuxbar"
测试操作:
$ ./test.sh
line1: hello
line2:
line3: hello
line4: hellolinuxbar
line2这一行,由于变量两侧没有加大括号,导致shell认为VARlinuxbar整体是一个变量。
因为我们并没有定义这个变量,所以输出为空。
小括号用来执行一条指令。
示例:打印当前的执行路径
测试脚本文件test.sh内容如下:
#!/bin/sh
PATH=$(pwd)
echo "PATH = ${PATH}"
意思是:先执行pwd这条指令,然后把执行结果赋值给变量PATH。
测试操作:
$ ./test.sh
PATH = /home/captain/tmp
除了使用$()之外,还可以使用键盘上ESC键下面的 ` 来执行一条指令。
shell - 单引号、双引号
示例:单引号中的变量不会扩展,双引号中的变量会进行扩展。
测试脚本文件test.sh内容如下:
#!/bin/bash
NAME="www.linuxbar.net"
echo 'my name is ${NAME}'
echo "my name is ${NAME}"
测试操作:
$ ./test.sh
my name is ${NAME}
my name is www.linuxbar.net
因为第一个echo语句中,使用的是单引号,所以变量没有扩展。
shell - 命令参数传递
- $# 命令行传入的参数个数
- $0 所执行脚本的文件名
- $1 命令行传入的第 1 个参数
- $N 命令行传入的第 N 个参数
- $$ 所执行脚本的进程号
- $? 上一条命令的执行结果
- $* 输出除了 $0 之外的其他所有参数
- $@ 与 $* 相同,要加上引号
传入参数个数不足时,后面的参数内容为空。
示例:接收命令行参数
测试脚本文件test.sh内容如下:
#!/bin/bash
echo "param num is: $#"
echo "param_0 = $0"
echo "param_1 = $1"
echo "param_2 = $2"
echo "param_3 = $3"
echo "pid = $$"
echo "params = $*"
echo "params = $@"
测试操作:
$ ./test2.sh aa bb
param num is: 2
param_0 = ./test2.sh
param_1 = aa
param_2 = bb
param_3 =
pid = 31747
params = aa bb
params = aa bb
因为测试指令中只传入了2个参数,所以$3为空。
shell - 数值计算
示例:计算数字的加减乘除。
测试脚本文件test.sh内容如下:
#!/bin/bash
NUM=4
val1=`expr ${NUM} + 2`
val2=$((${NUM} + 2))
val3=$((${NUM} * 2))
echo "val1 = ${val1}"
echo "val2 = ${val2}"
echo "val3 = ${val3}"
测试操作:
$ ./test.sh
val1 = 6
val2 = 6
val3 = 8
shell - 字符串操作
- = 检查两个字符串是否相等,相等返回真;
- != 检查两个字符串是否相等,不相等返回真;
- -z 检查字符串的长度是否为 0,为 0 返回真;
- -n 检查字符串的长度是否大于 0,大于 0 返回真;
- $ 检查字符串是否为空,不为空返回真;
示例:获取字符串的长度,提取字符串
测试脚本文件test.sh内容如下:
#!/bin/bash
NAME="linuxbar"
echo "length is: ${#NAME}"
echo "first 5 chars: ${NAME::5}"
echo "last 3 chars: ${NAME:5:3}"
测试操作:
$ ./test.sh
length is: 8
first 5 chars: linux
last 3 chars: bar
shell - if...else... 中的数字比较
if中的条件判断:
- -eq 是否相等(equal)
- -ne 是否不相等(not equal)
- -lt 小于(less than)
- -le 小于等于(less equal)
- -gt 大于(greater than)
- -ge 大于等于(greater eqal)
示例:数字比较
测试脚本文件test.sh内容如下
#!/bin/bash
NUM=$1
if [ ${NUM} -lt 5 ]; then
echo "${NUM} is less than 5"
elif [ ${NUM} -eq 5 ]; then
echo "${NUM} is equal 5"
elif [ ${NUM} -gt 5 ]; then
echo "${NUM} is greater than 5"
fi
测试操作:
$ ./test.sh 1
1 is less than 5
$ ./test.sh 5
5 is equal 5
$ ./test.sh 8
8 is greater than 5
如果在变量两侧加上双引号也是可以的("$NUM");
但是数字字面量的两侧不要加引号;
注意:对于数字和字符串的判断是不同的,比如判断是否“相等”:
- -eq 用于数字,不能用于字符串之间的比较;
- = 可以用于数字,也用于字符串;
shell - if...else... 中的字符串比较
示例:比较字符串
测试脚本文件test.sh内容如下
#!/bin/bash
NAME=$1
if [ "${NAME}" = "linux" ]; then
echo "name matched!"
else
echo "name does not matched!"
fi
测试操作:
$ ./test.sh hello
name does not matched!
$ ./test.sh linux
name matched!
shell - if...else... 中的逻辑操作
示例:多个条件判断结果的逻辑操作
测试脚本文件test.sh内容如下:
#!/bin/bash
NUM=10
if [ ${NUM} -gt 5 ] && [ ${NUM} -lt 100 ]; then
echo "aaa"
else
echo "bbb"
fi
if [ ${NUM} -gt 5 ] || [ ${NUM} -gt 100 ]; then
echo "ccc"
else
echo "ddd"
fi
测试操作:
$ ./test.sh
aaa
ccc
可以看出:逻辑操作符&& 、 || 是放在中括号的外面的。
也可以使用双中括号的形式,此时逻辑操作符&& 、 || 就放在中括号的里面,如下:
#!/bin/bash
NUM=10
if [[ ${NUM} -gt 5 && ${NUM} -lt 100 ]]; then
echo "aaa"
else
echo "bbb"
fi
if [[ ${NUM} -gt 5 || ${NUM} -gt 100 ]]; then
echo "ccc"
else
echo "ddd"
fi
shell - 文件或目录状态
文件相关的判断条件有:
- -f 检查某文件是否存在,且为普通文件;
- -c 检查某文件是否存在,且为字符设备;
- -b 检查某文件是否存在,且为块设备;
- -z 检查某文件或目录是否存在;
- -d 检查某文件是否为目录;
- -r 检查某文件是否可读;
- -w 检查某文件是否可写;
- -x 检查某文件是否可执行;
测试脚本文件test.sh内容如下:
#!/bin/sh
if [ -d /home/captain/tmp ]; then
echo "dir exists"
if [ -f /home/captain/tmp/test.sh ]; then
echo "file exists"
else
echo "file does not exists"
fi
else
echo "dir does not exixt"
fi
测试操作:
$ ./test.sh
dir exists
file exists
shell - 文件操作
示例:对某个目录下的文件进行批量重命名(加上后缀)。
测试脚本文件test.sh内容如下:
#!/bin/sh
DIR=${1}
SUFFIX=${2}
for f in `ls ${DIR}`
do
mv "${DIR}${f}" "${DIR}${f}.${SUFFIX}"
done
测试操作:
$ ls tmp/images/
t1 t2 t3 t4 t5
$
$ ./test.sh /tmp/images/ png
$
$ $ ls /tmp/images/
t1.png t2.png t3.png t4.png t5.png
shell - for 循环
在循环语句中,可以使用break和continue来控制循环操作,含义与 C 语言中的相同:
- break: 用来结束循环语句;
- continue: 用来跳过本次循环中的剩余指令,进入下一次循环。
示例:枚举所有字符串
测试脚本文件test.sh内容如下:
#!/bin/bash
FILE_LIST="aaa bbb ccc"
for name in ${FILE_LIST}
do
echo "${name}"
done
echo "--------------"
for name in ${FILE_LIST}; do
echo "${name}"
done
测试操作:
$ ./test.sh
aaa
bbb
ccc
--------------
aaa
bbb
ccc
示例:计算数字1 到 10的累加结果。
测试脚本文件test.sh内容如下:
#!/bin/bash
sum=0
for i in $(seq 10)
do
let sum=$sum+$i
done
echo "sum = ${sum}"
测试操作:
$ ./test.sh
sum = 55
示例:另外一种for形式来计算数字累加结果:
#!/bin/bash
sum=0
for ((i=1;i<=10;i++))
do
let sum=$sum+$i
# sum=$[$sum+$i] 另一种写法
done
echo "sum=${sum}"
测试操作:
$ ./test.sh
sum = 55
shell - while 循环
示例:计算数字1 到 10的累加结果。
测试脚本文件test.sh内容如下:
#!/bin/bash
i=1
sum=0
#while [ ${i} -le 10 ] 也可以
while [[ ${i} -le 10 ]]
do
sum=$[$sum+$i]
i=$[$i+1]
done
echo "sum=${sum}"
测试结果:
$ ./test.sh
sum=55
shell - until 循环
示例:计算数字1 到 10的累加结果。
测试脚本文件test.sh内容如下:
#!/bin/bash
i=1
sum=0
until [[ ${i} -gt 10 ]]
do
sum=$[$sum+$i]
i=$[$i+1]
done
echo "sum=${sum}"
测试结果:
$ ./test.sh
sum=55
shell - 函数
测试脚本文件test.sh内容如下:
#!/bin/bash
function MySum()
{
echo "param1 = $1"
echo "param2 = $2"
val=$(($1 + $2))
return ${val}
}
MySum 10 20
echo "result = $?"
测试结果:
$ ./test.sh
param1 = 10
param2 = 20
result = 30
函数的定义中,function可以省略不写。
在函数体中,函数的返回值只能是0 ~ 255。
如果函数中没有明确的return语句,那么函数中最后一条语句的执行结果就是返回值。
调用者通过$?来获取函数的返回结果。
shell - 其它常用命令
示例:获取当前所执行脚本的绝对路径:
MYDIR=$(cd $(dirname $0); pwd)
示例:输出结果重定向:
./xxxx.sh >/dev/null 2>&1
示例:获取进程的PID
ps -x | grep 程序名称 | grep -v grep | awk '{print $1}'

Linux 茶馆
