Shell 变量
定义
定义变量时,变量名和等号之间不能有空格,命名规则如下:
- 只能使用英文字母、数字和下划线,首个字符不能为数字
- 中间不能有空格, 使用下划线代替
- 不能使用标点符号
- 不能使用 bash 中的关键字
使用
使用一个定义过的变量,在变量名前面加美元符号,如
也可以添加花括号帮助解释器识别变量的边界
1 2
| user='DF' echo "This callable from ${user}'s bash"
|
只读变量
使用readonly
设置只读变量
1 2 3
| #!/bin/bash user='DF' readonly user
|
删除变量
使用unset
删除变量
变量类型
运行 shell 时,存在 环境变量、shell 变量、局部变量 三种
- 环境变量就是系统变量;
- shell 变量是由 shell 程序设置的特殊变量,一部分是环境变量;一部分为局部变量;
- 在脚本或命令中定义的,仅在当前 shell 实例中有效的变量。
Shell 字符串
单引号
单引号中的任何字符都会以原样输出,单引号字符串中的变量是无效的;
单引号字串中不能出现单独一个的单引号(使用转义符也不行),但可以成对使用,用于字符串拼接。
双引号
1 2
| user='DF' str="this mechine is named of ${user}"
|
双引号里面可以有变量,可以出现转义字符。
字符串拼接
1 2 3 4 5 6 7
| user='DF' id='0001'
temp1='name:'$user' id:'$id''
temp2="name:${user} id:${id}" temp3="name:"$user" id:"$id""
|
字符串长度
1 2
| string='abcd' echo ${#string}
|
提取子字符串
1 2
| str='abcdefghigklmn' echo ${str:2:5}
|
查找子字符串
1 2 3
| str = 'ABCDEFGHIGKLMN'
echo `expr index "$str" B`
|
数组
用括号表示数组,数组元素用“空格”符号分割开
使用 name[]
索引,使用@
获取所有元素
1 2 3 4 5
| echo ${name[0]} echo ${name[1]} echo ${name[2]} echo ${name[4]} echo ${name[@]}
|
数组长度
1 2
| echo ${#name[*]} echo ${#name[@]}
|
注释
单行注释使用#
多行注释使用:<<
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
:<<! 这是一个bash文件 作者为DF !
:<<EOF 这是一个bash文件 作者为DF EOF
|
Shell 传递参数
从命令行想 Shell 脚本传递参数,脚本内通过$n (n=0,1,2...)
获取
还存在几个特殊字符用于处理参数
命令 |
含义 |
$# |
传递到脚本参数的数量 |
$* |
以一个字符串的形式返回所有参数 |
$@ |
以不同字符串的形式返回传递的参数 |
$$ |
脚本运行的当前进程ID号 |
$! |
后台运行的最后一个进程 ID 号 |
$- |
显示Shell使用的当前选项 |
$? |
显示最后命令的退出状态 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
echo '$*' for i in "$*";do echo $i done echo '$@' for i in "$@";do echo $i done
bash test.sh 1 2 3
$* 1 2 3 $@ 1 2 3
|
基本运算符
算数运算符
原生的 bash 中不支持简单的数学运算,但可以利用expr
或者awk
实现,常用的为expr
1 2 3 4 5 6 7 8
| #!/bin/bash echo `expr 1 + 1` echo `expr 1 - 1` echo `expr 2 \* 2 ` echo `expr 2 / 2` echo `expr 2 % 2` [ 2 == 2 ] [ 2 != 2 ]
|
注意:条件表达式要放在方括号中间,并且要加空格,这与赋值表达式不
表达式需要被 ` ` 包围
关系运算符
运算符 |
说明 |
示例 |
-eq |
判断两边相等 |
[ 10 -eq 10 ] 返回 true |
-ne |
判断两边不等 |
[ 10 -ne 10 ] 返回 false |
-gt |
判断左边大于右边 |
[ 10 -gt 15 ] 返回 false |
-lt |
判断左边小于右边 |
[ 10 -lt 15 ] 返回 true |
-ge |
判断左边大于等于右边 |
[ 15 -ge 15 ] 返回 true |
-le |
判断左边小于等于右边 |
[ 15 -le 15 ] 返回 true |
布尔运算符
运算符 |
说明 |
示例 |
! |
非运算 |
[ !false ] 返回 true |
-o |
或运算 |
[ true -o false ] 返回 true |
-a |
与运算 |
[ true -a false ] 返回 false |
逻辑运算符
运算符 |
说明 |
示例 |
&& |
逻辑 AND |
[[ true && false ]] 返回 false |
|| |
逻辑 OR |
[[ true || false ]] 返回 true |
补充:布尔运算符与逻辑运算符的区别
1 2 3 4 5 6
| 1. 语法方面 布尔运算符使用 [单括号];而逻辑运算符使用 [[双括号]] 2. 运算方面 逻辑运算符具有特殊的短路功能,可以利用这一特性实现用命令 1 的执行结果控制命令 2 执行的效果 [[ cmd1 && cmd2 ]] 当 cmd1==false 时,cmd2 不执行 [[ cmd1 || cmd2 ]] 当 cmd1==true 时,cmd2 不执行
|
补充: shell 中的状态码
1 2 3
| shell 中每个表达式执行完退出时,都会返回一个状态码(exit status 0~255),在这些状态码中,0 表示执行成功,1~255 为退出的状态代码。 在判断语句中,[condition]为判断符,其中条件为真返回 0,假返回 1。 在 C 语言中,存在 while(1)的用法,但与 shell 中 if[ 1 ]的表达不同,c 语言中`1`表示为 True;而 shell 中[ num ]返回状态码 0,无论 num 具体为何数,均返回状态码 0。
|
字符串运算符
运算符 |
说明 |
示例 |
= |
判断两个字符串是否相等 |
[ abc = abc ] 返回 true |
!= |
判断两个字符串是否不等 |
[ abc != abc] 返回 false |
-z |
判断字符串长度是否为零 |
[ -z abc] 返回 false |
-n |
判断字符串长度是否不为零 |
[ -n abc] 返回 true |
$ |
检测字符串是否为空 |
[ $ ‘’ ] 返回 true |
文件测试运算符
用于测试 Unix 文件的各种属性
运算符 |
说明 |
-d file |
是否是目录 |
-f file |
是否是普通文件 |
-r file |
是否可读 |
-w file |
是否可写 |
-x file |
是否可执行 |
-s file |
是否为空 |
-e file |
检擦文件或目录是否存在 |
echo 命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| echo "are you ok" echo are you ok
echo \" are you ok \" echo "\" are you ok \""
read name echo "$name are you ok"
echo -e "are you ok \n"
echo -e "are you ok \c"
echo "are you ok" >> leijun
echo '${leijun}: are you ok'
echo `date`
|
printf 命令
1 2 3 4 5 6 7 8 9
| printf format-string [arguments]
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
|
流程控制
if 条件语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| if condition then command fi
if condition then command1 else command2 fi
if condition1 then command1 elif command2 else command3 fi
|
for 循环语句
1 2 3 4
| for var in item1 item2 item3 do command done
|
while 循环语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| while condition do command done
while : do command done
for (( ; ; ))
|
until 循环
1 2 3 4
| until condition do command done
|
case
1 2 3 4 5 6 7 8 9 10 11
| case var in condition1) command ;; condition2) command ;; *) command ;; esac
|
break and continue
函数
1 2 3 4 5
| function funcname() { command return var }
|
- 函数定义时,可以待 function,也可以没有;但函数必须在使用前定义;
- 当存在 return 语句时,返回后面的内容;否则,返回最后一条命令运行的结果;
- 函数返回值通过
$?
获得
- 在函数体内部,函数的参数通过
$n
获得;当 n>=10 时,需采用${n}
输入/输出重定向
大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回 到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。
命令 |
说明 |
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 是标准输入,1 是标准输出,2 是标准错误输出
示例
1 2 3 4 5 6 7 8 9 10
| command 2 > file
command 2 >> file
command > file 2>&1
command >> file 2>&1
|
/dev/null
写入到 /dev/null
的内容都会被其丢弃,并且从其中读不到任何东西,将输出重定向到此文件,可以起到“禁止输出”的效果。
文件包含
1 2 3
| . filename
source filename
|
Shell 中各种括号的作用
()
- 命令组 括号中的命令会新开一个子 shell 按顺序执行,同时也因此导致括号中的变量不能被其他部分使用;括号中的多个命令使用
;
分隔开,最后一个命令不用分号,命令与括号之间无需空格
- 命令替换 $(command) 相当于 `cmd`
- 初始化数组 array=(a b c)
(())
- 整数拓展 整数型的计算
((expression))
,如果表达式结果为 0,则返回状态码 1;表达式结果非零,则返回状态码 0
- 运算 $((expression))可以进行符合 C 语言运算规则的运算
- 重定义变量 a=5;((a++))将$a 重定义为 6
- 算术运算比较,双括号中的变量可以不使用$前缀,多个表达式用逗号分开。
for((i=0;i<5;i++))
[]
- 内部命令,与 test 等同 可以用于条件判断,运算比较表达式或者条件测试,根据比较结果返回状态码
- []与 test 中可以使用的运算比较符只有==和!=,两者都是用于字符串比较,不可用于整数比较,整数比较只能使用-eq、-gt 等,同时通过转义字符,可以使用大于号和小于号,逻辑与和逻辑或通过-a 和-o 实现。
- 字符范围 作为正则表达式的一部分
- 引用数组中的元素
[[]]
- [[是 bash 中的关键字
- 支持字符串的模式匹配,使用=~操作符时支持 shell 的正则表达式
- 使用[[]]进行条件判断时,可以使用逻辑操作符
- bash 把[[]]中的表达式看作为一个单独的元素,并返回一个退出状态码。
{}
$后的括号
- ${a} 变量 a 的值
- ${cmd} 命令替换
- $((expression)) 计算括号中的数值
多条命令
1 2 3 4 5
| (cmd1;cmd2;cmd3)
{ cmd1;cmd2;cmd3;}
|