shell
常用于服务器上编译部署脚本、文件归档等场景。此文记录常用的语法,方便后续使用查找。
变量
常用系统变量
$HOME、 $PWD、 $SHELL、 $USER 等
特殊变量
- $n
n 为数字, $0 代表该脚本名称, $1-$9 代表第一到第九个参数, 十以上的参数, 十以上的参数需要用大括号包含, 如${10}
- $#
获取所有输入参数个数, 常用于循环,判断参数的个数是否正确以及加强脚本的健壮性
- $*、 $@
代表命令行中所有的参数,$*把所有的参数看成一个整体 ,$@把每个参数区分对待 - $?
最后一次执行的命令的返回状态。 如果这个变量的值为 0, 证明上一个命令正确执行; 如果这个变量的值为非 0(具体是哪个数, 由命令自己来决定) , 则证明上一个命令执行不正确
字符串处理
- 获取字符串长度
${#string}
获取字符串string的长度${string:1:4}
截取字符串,从第2个字符开始,截取长度为4
- 查找字符串
查找字符 i 或 o 的位置(哪个字母先出现就计算哪个)
1 | string="runoob is a great site" |
数组
数组的定义用小括号包裹,数组的值之间用空格区隔
1 | array_name=(value0 value1 value2 value3) |
数组的读取
${array_name[n]}
获取数组的某一项${array_name[@]}
获取数组所有参数${#array_name[@]}、${#array_name[*]}
获取数组元素的个数
运算符
$((运算式)) 或 $[运算式]
关系运算符
-eq | 检测两个数是否相等,相等返回 true。 |
---|---|
-ne | 检测两个数是否不相等,不相等返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 |
布尔运算符
! | 非运算,表达式为 true 则返回 false,否则返回 true。 |
---|---|
-o | 或运算,有一个表达式为 true 则返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 |
逻辑运算符
&& | 逻辑的 AND |
---|---|
|| | 逻辑的 OR |
字符串运算符
= | 检测两个字符串是否相等,相等返回 true。 |
---|---|
!= | 检测两个字符串是否不相等,不相等返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 |
-n | 检测字符串长度是否不为 0,不为 0 返回 true。 |
$ | 检测字符串是否为空,不为空返回 true。 |
文件测试运算符
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 |
---|---|
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 |
-r file | 检测文件是否可读,如果是,则返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 |
流程控制
if判断
基本语法
1 | # 单分支 |
举个栗子
1 |
|
case语法
基本语法
1 | case $变量名 in |
注意事项:
(1) case 行尾必须为单词“in” , 每一个模式匹配必须以右括号“) ” 结束。
(2) 双分号“;;” 表示命令序列结束, 相当于 java 中的 break。
(3) 最后的“*) ” 表示默认模式, 相当于 java 中的 default。
for循环
基本语法
1 | for (( 初始值;循环控制条件;变量变化 )) |
举个栗子
1 |
|
for…in语法
1 | for 变量 in 值 1 值 2 值 3… |
举个栗子
1 |
|
while循环
基本语法
1 | while [ 条件判断式 ] |
举个栗子
1 |
|
读取控制台输入
- 基本语法
read (选项) (参数)
①选项:
-p: 指定读取值时的提示符;
-t: 指定读取值时等待的时间(秒) 如果-t 不加表示一直等待
②参数
变量: 指定读取值的变量名
- 举个栗子
1
2
3
4
read -t 7 -p "Enter your name in 7 seconds :" NN
echo $NN
函数
系统函数
basename
- 基本语法
basename [string / pathname] [suffix] ( 功能描述: basename 命令会删掉所有的前缀包括最后一个(‘/’) 字符, 然后将字符串显示出来。
basename 可以理解为取路径里的文件名称
选项:
suffix 为后缀, 如果 suffix 被指定了, basename 会将 pathname 或 string 中的 suffix 去掉
dirname 文件绝对路径 (功能描述: 从给定的包含绝对路径的文件名中去除文件名(非目录的部分) , 然后返回剩下的路径(目录的部分) )
dirname 可以理解为取文件路径的绝对路径名称
举个栗子
1
2
3# /home/lazy5
dirname /home/lazy5/banzhang.txt自定义函数
基本语法
1
2
3
4
5[ function ] funname[()]
{
Action;
[return int;]
}说明
(1) 必须在调用函数地方之前, 先声明函数, shell 脚本是逐行运行。 不会像其它语言一
样先编译。
(2) 函数返回值, 只能通过$?系统变量获得, 可以显示加: return 返回, 如果不加, 将
以最后一条命令运行结果, 作为返回值。 return 后跟数值 n(0-255)
举个栗子
1
2
3
4
5
6
7
8
9
10
function sum()
{
s=0
s=$[$1+$2]
echo "$s"
}
read -p "Please input the number1: " n1;
read -p "Please input the number2: " n2;
sum $n1 $n2;文件包含
基本语法
1
2
3
4
5. filename # 注意点号(.)和文件名中间有一空格
或
source filename举个栗子
test1.sh 代码如下:
1 |
|
test2.sh 代码如下:
1 |
|
输入/输出重定向
命令 | 说明 |
---|---|
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 之间的内容作为输入。 |
需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)
输出重定向
基本语法
1
command1 > file1
举个栗子
1
2
3
4
5
6
7
8# 将who命令的结果输出到文件users
who > users
# 替换users的内容
echo "替换内容" > users
# 追加内容到users
echo "追加内容" >> users
输入重定向
基本语法
1
command1 < file1
举个栗子
1
2
3
4
5# 会输出2 users,行数+文件名
wc -l users
# 此处直接输出2,只显示行数,因为wc只知道是从标准输入读取的内容
wc -l < users
同时输出/输入
1 | command1 < infile > outfile |
command1 < infile > outfile
重定向深入讲解
一般情况下,每个 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。
如果希望 stderr 重定向到 file,可以这样写:
1 | command 2>file |
如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:
1 | command > file 2>&1 |
如果希望对 stdin 和 stdout 都重定向,可以这样写:
1 | command < file1 >file2 |
/dev/null 文件
如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:
1 | command > /dev/null |
如果希望屏蔽 stdout 和 stderr,可以这样写:
1 | command > /dev/null 2>&1 |