shell 基本语法
这里记录下shell脚本语言的学习
shall是用c语言编写的程序,用于让用户使用Linux,但shall脚本和c的编程格式并不一样
Shall的种类颇多,菜鸟教程里介绍的shall是Bash
唉,大学三年简直白混了,临到毕业疯狂补习基础知识,要不得啊
运行
-
添加可执行权限
$ chmod +x test.sh $ ./test.sh -
作为解释器参数
$ /bin/sh test.sh
变量
定义变量:等号前后不能加空格 name="myname"
使用变量:echo ${your_name} 花括号可加可不加,但若如同 echo ${your_name}is? ,后面跟字符串或其它内容,而且中间没东西隔开的话一定要加。
只读变量:readonly name
删除变量:unset your_name ,不能删除只读变量
变量类型:
- 局部变量
- 环境变量
- shell变量:由shell程序设置的特殊变量,包含环境变量和局部变量
字符串
单引号、双引号和不加引号都可以定义字符串,但使用场景不同
单引号:所有字符都会原样输出,包括用$表示的变量和转义字符
双引号:里边可以正常显示变量和转义字符
单、双引号里都不允许出现单个的引号,但可以成对出现,代表拼接字符串
str='name'is'yiyuzi'
获取长度:${#str}
提取子串:${string:1:4}
查找子串:查找 i 或 o 最先出现的位置,注意前后是反引号

数组
不支持多维数组,但没有限定数组大小
定义:括号表示,里边用空格隔开,也可以换行隔开,或像c里一样用下标赋值
arr=(v1 v2 v3)
读取元素:${arr[n]}
读取数组所有元素:${arr[@]}
获取数组长度:${#arr[@]} 或 ${#arr[*]}
获取单个元素长度:${#arr[n]}
注释
单行注释:行首加 #
多行注释:
-
每行前都加#
-
把要注释的用花括号括起来,定义成函数,但不调用
-
:<<EOF 注释块 EOF :<<' 注释块 ' :<<! 注释块 !
传递参数
| 参数处理 | 说明 |
|---|---|
| $# | 传递到脚本的参数个数 |
| $* | 以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
| $$ | 脚本运行的当前进程ID号 |
| $! | 后台运行的最后一个进程的ID号 |
| $@ | 与\(*相同,但是使用时加引号,并在引号中返回每个参数。 如"\)@"用「"」括起来的情况、以"$1" "\(2" … "\)n" 的形式输出所有参数。 |
| $- | 显示Shell使用的当前选项,与set命令功能相同。 |
| $? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
$ chmod +x test.sh
$ ./test.sh 1 2 3
Shell 传递参数实例!
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3
参数中如果包含空格,应该用引号括起来
运算符
算数运算符:和c一样
关系运算符:不支持字符串
| 运算符 | 说明 | 举例 |
|---|---|---|
| -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 -eq $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。 |
逻辑运算符:&&和||
字符串运算符:
| 运算符 | 说明 | 举例 |
|---|---|---|
| = | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
| != | 检测两个字符串是否不相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
| -z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
| -n | 检测字符串长度是否不为 0,不为 0 返回 true。 | [ -n "$a" ] 返回 true。 |
| $ | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
文件测试运算符:
| 操作符 | 说明 | 举例 |
|---|---|---|
| -b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
| -c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
| -d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
| -f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
| -g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
| -k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
| -p file | 检测文件是否是有名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
| -u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
| -r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
| -w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
| -x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
| -s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
| -e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
echo
会自动添加换行,可以用\c取消
printf
printf 比 echo 的移植性好些
printf不会自动换行
格式化输出的方式和c一样
# format-string为双引号
printf "%d %s\n" 1 "abc"
# 单引号与双引号效果一样
printf '%d %s\n' 1 "abc"
# 没有引号也可以输出
printf %s abcdef
# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf %s abc def
printf "%s\n" abc def
printf "%s %s %s\n" a b c d e f g h i j
# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d \n"
1 abc
1 abc
abcdefabcdefabc
def
a b c
d e f
g h i
j
and 0
转义序列:
| 序列 | 说明 |
|---|---|
| \a | 警告字符,通常为ASCII的BEL字符 |
| \b | 后退 |
| \c | 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略 |
| \f | 换页(formfeed) |
| \n | 换行 |
| \r | 回车(Carriage return) |
| \t | 水平制表符 |
| \v | 垂直制表符 |
| \ | 一个字面上的反斜杠字符 |
| \ddd | 表示1到3位数八进制值的字符。仅在格式字符串中有效 |
| \0ddd | 表示1到3位的八进制值字符 |
test
可以检测数值、字符、文件
a=100
b=100
if test $[a] -eq $[b]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
result=$[a+b] # 注意等号两边不能有空格
echo "result 为: $result"
str1="ru1noob"
str2="runoob"
if test $str1 = $str2
then
echo '两个字符串相等!'
else
echo '两个字符串不相等!'
fi
# 另外,Shell 还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为: ! 最高, -a 次之, -o 最低。
if test -e ./notFile -o -e ./bash
then
echo '至少有一个文件存在!'
else
echo '两个文件都不存在'
fi
条件控制
if 形如上文,else if 写作elif,可以不换行,写法如下
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
for var in item1 item2 ... itemN; do command1; command2… done;
while condition
do
command
done
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
site="runoob"
case "$site" in
"runoob") echo "菜鸟教程"
;;
"google") echo "Google 搜索"
;;
"taobao") echo "淘宝网"
;;
esac
# 有break和continue
函数
-
可以带function fun() 定义,也可以直接fun() 定义,函数体用花括号括起来。
-
函数定义不带任何参数,传递参数是用$n。
注意,$10 不能获取第十个参数,获取第十个参数需要 ${10}。当n>=10时,需要使用${n}来获取参数。
-
参数返回,可以 return 返回,如果不加,将以最后一条命令运行结果,作为返回值。
函数返回值在调用该函数后通过 $? 来获得。
输出/输出重定向
| 命令 | 说明 |
|---|---|
| command > file | 将输出重定向到 file。 |
| command < file | 将输入重定向到 file。 |
| command >> file | 将输出以追加的方式重定向到 file。 |
| n > file | 将文件描述符为 n 的文件重定向到 file。 |
| n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
| n >& m | 将输出文件 m 和 n 合并。 |
| n <& m | 将输入文件 m 和 n 合并。 |
| << tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |

浙公网安备 33010602011771号