运行shell脚本的三种方法:
-
方法1:chmod +x ./test.sh;./test.sh -作为可执行程序,需要执行权限
-
方法2:source test.sh -在当前 bash 环境下读取并执行文件中的命令,无需执行权限。或 . test.sh
-
在shell语法中执行linux命令:
-
方法1:echo `pwd`
-
方法2:echo $(pwd)
变量使用:
-
变量定义:val=jack 等价于 val='jack' 等价于 val="jack";=两边不允许有空格
-
变量引用:echo $val 等价于 echo ${val} 推荐加{} 有助于识别变量边界
-
只读变量:readonly val
-
删除变量:unset val
-
字符串拼接:echo 'hello '${val}" world"
-
字符串切片:echo ${val:1:3}
-
字符串截取:路径处理时常用
# 字符串截取(界定字符本身也会被删除)
str="www.runoob.com/linux/linux-shell-variable.html"
echo "str : ${str}"
echo "str#*/ : ${str#*/}" # 从 字符串开头 删除到 左数第一个'/'
echo "str##*/ : ${str##*/}" # 从 字符串开头 删除到 左数最后一个'/'
echo "str%/* : ${str%/*}" # 从 字符串末尾 删除到 右数第一个'/'
echo "str%%/* : ${str%%/*}" # 从 字符串末尾 删除到 右数最后一个'/'
# 输出结果
str : www.runoob.com/linux/linux-shell-variable.html
str#*/ : linux/linux-shell-variable.html
str##*/ : linux-shell-variable.html
str%/* : www.runoob.com/linux
str%%/* : www.runoob.com
数组使用:
-
数组定义:array_name=(value0 value1 value2 value3)
-
数组元素值获取:valuen=${array_name[n]}
-
获取数组所有元素:echo ${array_name[@]} 等价于 echo ${array_name[*]}
-
获取数组元素个数:length=${#array_name[*]}
注解:单行使用#
脚本参数传递:
本传递的参数中如果包含空格,应该使用单引号或者双引号将该参数括起来,以便于脚本将这个参数作为整体来接收.
表达式计算:
-
expr 5 + 6:运算间要有空格 等价于$[1+2]
-
r=$[a+b]:无需空格
-
对于用反引号括起的表达式需要赋值给变量或直接echo才能使用:val=`expr 5 + 6`
-
val=$((1+2)):无需空格
-
val=$(expr 5 + 6):相比第3种,更推荐这种
键盘输入信息:read -p "input a val:" a 获取键盘输入赋值给a,-p设置提示信息
算术运算符:
-
'*':使用特殊运算符要转义
-
==、!=:方括号之间要有空格
if [ $a != $b ]
then
echo "a 不等于 b"
fi
关系运算符:只支持数字不支持非数字的字符串
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否不相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
a=10
b=20
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b"
布尔运算符:
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
逻辑运算符: 作用上与布尔运算符一样,但写法上不同,逻辑运算符用在[[]]中,用在[]中会报错应用布尔运算符替换
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| | 逻辑的 OR | [[ $a -lt 100 || $b -gt 100 ]] 返回 true |
1、进行数值比较时,可以使用 [ expression1 OPexpression2 ],OP 可以为 -gt、-lt、-ge、-le、-eq、-ne 也可以使用 ((expression1 OP expression2)),OP 可以为 >、<、>=、<=、==、!=。这几个关系运算符都是测试整数表达式 expression1 和 expression2 之间的大小关系。
2、 >、<、==、!= 也可以进行字符串比较。
3、进行字符串比较时,== 可以使用 = 替代。
4、 == 和 !=进行字符串比较时,可以使用 [ string1 OP string2 ] 或者 [[ string1 OP string2 ]] 的形式。
5、 > 和 < 进行字符串比较时,需要使用[[ string1 OP string2 ]] 或者 [ string1 OP string2 ]。也就是使用 [] 时,> 和 < 需要使用反斜线转义。
[] 表达式
注意:在 [] 表达式中,常见的 >, < 需要加转义字符,表示字符串大小比较,以 acill 码位置作为比较。不直接支持 >, < 运算符,还有逻辑运算符 || 、&& ,它需要用 -a[and] –o[or] 表示。
[[ ]] 表达式
注意:[[]] 运算符只是 [] 运算符的扩充。能够支持 >, < 符号运算不需要转义符,它还是以字符串比较大小。里面支持逻辑运算符:|| && ,不再使用 -a -o。
判断字符串是否为空:
-
-n:字符串长度不为0返回true(对于未定义变量和""空串均为false). if [ -n "$a" ] 或 if [[ -n $a ]] 禁用 if [ -n $a ]. 建议使用双括号
-
-z:字符串长度为0返回true(对于未定义变量和""空串均为true) . if [ -z $a ] 或 if [[ -z $a ]] 推荐后者
-
$:直接使用变量判断长度不为0返回true. 等价于 -n. if [ $a ] 或 if [[ $a ]] 推荐后者
-
貌似无法区分变量是否存在与变量是否为空字符串,对于未定义的变量默认值为空字符串
文件测试运算符:建议if判断均使用双括号
-
-d:判断是否为目录,若是为true
-
-f:判断是否为文件,若是为true
-
-r/-w/-x:判断文件是否可读可写可执行,若是为true
-
-s:判断文件是否非空(大小>0)
-
-e:判断文件/目录是否存在,若存在为true
echo输出命令:自动在末尾添加换行符
-
echo -e "OK! ":开启转义(默认原样输出).
-
echo -e "OK! c"; echo "jack":c不换行
-
单引号:任何字符原样输出(换行符、tab符等文本格式符除外),引用变量无效,引用转义字符无效(eg:"原样输出)
-
反引号``:将一个命令的标准输出插在原命令行中. 或者$(...)结构括起来,其中,$(...)格式受到POSIX标准支持,也利于嵌套。
-
双引号:能引用变量,能引用转义符,能引用文本格式符
-
能否引用变量 能否引用转义符 能否引用文本格式符(如:换行符、制表符) 单引号 否 否 能 双引号 能 能 能 无引号 能 能 否
printf格式化输出:
-
默认不会在末尾添加换行符,以空格分隔参数
-
printf "%-10s %-8s %-4.2f " 郭靖 男 66.1234
-
%s %c %d %f都是格式替代符
-
%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
-
%-4.2f 指格式化为小数,其中.2指保留2位小数。
read输入命令:
-
read 命令一个一个词组地接收输入的参数,每个词组需要使用空格进行分隔;如果输入的词组个数大于需要的参数个数,则多出的词组将被作为整体为最后一个参数接收。
-
-p 输入提示文字;-n 输入字符长度限制(达到6位,自动结束);-t 输入限;-s 隐藏输入内容
重定向输入输出:
> 重定向输出到某个位置,替换原有文件的所有内容。
>> 重定向追加到某个位置,在原有文件的末尾添加内容。
< 重定向输入某个位置文件。
2> 重定向错误输出。
2>> 重定向错误追加输出到文件末尾。
&> 混合输出错误的和正确的都输出。
command > file 2>&1:将 stdout 和 stderr 合并后重定向到 file
一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。
放在>后面的&,表示重定向的目标不是一个文件,而是一个文件描述符.换言之 2>1 代表将stderr重定向到当前路径下文件名为1的regular file中,而2>&1代表将stderr重定向到文件描述符为1的文件(即/dev/stdout)中,这个文件就是stdout在file system中的映射.而&>file是一种特殊的用法,也可以写成>&file,二者的意思完全相同,都等价于 >file 2>&1
如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:command > /dev/null
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。如果希望屏蔽 stdout 和 stderr,可以这样写:
command > /dev/null 2>&1
命令 | 说明 |
---|---|
command > file | 将输出重定向到 file。 |
command < file | 将输入重定向到 file。 |
command >> file | 将输出以追加的方式重定向到 file。 |
n > file | 将文件描述符为 n (0/1/2)的文件重定向到 file。 |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
n >& m | 将输出文件 m 和 n 合并。 |
n <& m | 将输入文件 m 和 n 合并。 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
test命令:if test $val1 == $val2 等价于 if [ $val1 == $val2 ]
shell条件判断除空串和未定义变量为false,其余均为true(包括零)
shell 语言中 0 代表 true,0 以外的值代表 false
流程控制:
a=10
b=20
if [ $a == $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "没有符合的条件"
fi
# 写成一行
if [ $a == $b ]; then echo "a 等于 b"; else echo "a 不等于 b"; fi
for循环:
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
# 写成一行
for var in item1 item2 ... itemN; do command1; command2… done;
# 写法2:
for((assignment;condition:next));do
command_1;
command_2;
commond_..;
done;
for((i=1;i<=5;i++));do
echo "这是第 $i 次调用";
done;
# 通常情况下 shell 变量调用需要加 $,但是 for 的 (()) 中不需要
while循环:
int=1
while(( $int<=5 )) 等价于 while [ $int -le 5 ]
do
echo $int
let int++
done
# 从键盘读取输入知道ctrl+d终止
while read FILM
do
echo "是的!$FILM 是一个好网站"
done
case:
case 值 in
模式1)
command1
command2
command3
;;
模式2)
command1
command2
command3
;;
*)
command1
command2
command3
;;
esac
# break或continue的使用
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
break # 或continue
echo "hah"
;;
esac
done
函数:
[ function ] funname [()]
{
action;
[return int;]
}
1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255
--- 示例1:
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum 和 $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
--- 函数参数:
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
--- 0为true,非0均为false
function demoFun1(){
return 0
}
function demoFun2(){
return 12
}
if demoFun1
then
echo true # true
else
echo false
fi
if demoFun2
then
echo ture
else
echo false # false
fi
脚本引用:在脚本中执行其他脚本
. test1.sh 等价于 source test1.sh