Shell 基础 ¶
#linux #命令行 #shell #脚本编程
常规 ¶
数据类型:除了在进行运算时,其它时候一律按照字符串类型处理
变量:变量定义时不加$符号,访问时加$符号,有歧义时用{}包含变量名,如${a}
括号
双括号 (( expr )), 进行算术或逻辑运算,表达式(操作数)间可有空格,也可没有空格
双中括号 [[ expr ]], 进行逻辑运算,运算符与操作数必须留空格 [[ -x /bin/su ]]
单中括号 [ expr ], 进行逻辑运算,或者用于文件判断等,比如 [ -x /bin/su ]
大括号${var}, 变量var的值,无歧义时使用$var
单中括号( subshell ), 子Shell
双大括号执行结果可以认为是一个匿名变量,要取值需要使用$,如 b=$(( var ))
连接符号
&& 连接两个命令,前面的执行成功后执行后面的
|| 连接两个命令或者操作,前面的执行失败后执行后面的
; 连接两个命令或者操作,前面的执行后依次执行后面的,不关心命令执行结果
命令的执行结果:命令成功或者失败以$?变量标识,如果成功则$?=0,否则$?=其它值
流程控制 ¶
选择支:if
# 表达式一、相当于一行一条命令,if,then,fi这些都是有依赖关系的shell命令
# then 指令后给需要执行的命令,如果需要执行多条指令则进行折行
if statement
then
command
fi
# 表达式2:将多条命令放在一行,所以需要用分号(;)分割
if statement; then command; fi 简化为: [[ statement ]] && command
# 表达式3:
if [[ ! statement ]]; then command; fi 简化为: [[ statemnet ]] || command
选择支:case
# 这个麻烦一点,要记一下
case $var in
"value1")
state-1
;;
"value2")
state-2
;;
*)
default-statement
;;
esac
循环控制
# 表达式1:形式上和if结构一致
for statemnet
do
command
done
# 表达式二
for statements; do command; done
子过程 ¶
# 一、定义子程序
proc_name(){
statements
}
# 二、运行子程序
proc_name
# 三、获取子程序传参
proc_name(){
echo $1,$2,$3
}
# 四、调用传参
proc_name a b c
Tricks ¶
获取Shell脚本所在的位置
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
仅可用于BASH终端,因为其他终端不支持 BASH_SOURCE 变量
附:关于if选择支的表达式 ¶
see also: https://www.cnblogs.com/viiv/p/15771513.html
文件和文件夹 ¶
[ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真。
[ -c FILE ] 如果 FILE 存在且是一个字特殊文件则为真。
[ -d DIR ] 如果 FILE 存在且是一个目录则为真。
[ -e FILE ] 如果 FILE 存在则为真。
[ -f FILE ] 如果 FILE 存在且是一个普通文件则为真。
[ -g FILE ] 如果 FILE 存在且已经设置了SGID则为真。
[ -k FILE ] 如果 FILE 存在且已经设置了粘制位则为真。
[ -p FILE ] 如果 FILE 存在且是一个名字管道(F如果O)则为真。
[ -r FILE ] 如果 FILE 存在且是可读的则为真。
[ -s FILE ] 如果 FILE 存在且大小不为0则为真。
[ -t FD ] 如果文件描述符 FD 打开且指向一个终端则为真。
[ -u FILE ] 如果 FILE 存在且设置了SUID (set user ID)则为真。
[ -w FILE ] 如果 FILE存在且是可写的则为真。
[ -x FILE ] 如果 FILE 存在且是可执行的则为真。
[ -O FILE ] 如果 FILE 存在且属有效用户ID则为真。
[ -G FILE ] 如果 FILE 存在且属有效用户组则为真。
[ -L FILE ] 如果 FILE 存在且是一个符号连接则为真。
[ -N FILE ] 如果 FILE 存在 and has been modied since it was last read则为真。
[ -S FILE ] 如果 FILE 存在且是一个套接字则为真。
[ FILE1 -nt FILE2 ] 如果 FILE1 has been changed more recently than FILE2, or 如果 FILE1 exists and FILE2 does not则为真。
[ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 要老, 或者 FILE2 存在且 FILE1 不存在则为真。
[ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则为真。
数值判断 ¶
[ INT1 -eq INT2 ] # INT1和INT2两数相等为真 ,=
[ INT1 -ne INT2 ] # INT1和INT2两数不等为真 ,<>
[ INT1 -gt INT2 ] # INT1大于INT1为真 ,>
[ INT1 -ge INT2 ] # INT1大于等于INT2为真,>=
[ INT1 -lt INT2 ] # INT1小于INT2为真 ,<</div>
[ INT1 -le INT2 ] # INT1小于等于INT2为真,<=
字符串比较 ¶
[ -z STRING ] 如果STRING的长度为零则为真 ,即判断是否为空,空即是真;
[ -n STRING ] 如果STRING的长度非零则为真 ,即判断是否为非空,非空即是真;
[ STRING1 = STRING2 ] 如果两个字符串相同则为真 ;
[ STRING1 != STRING2 ] 如果字符串不相同则为真 ;
[ STRING1 ] 如果字符串不为空则为真,与-n类似
表达式替换 ¶
${var} # 变量var的值, 与$var相同
${var-DEFAULT} # 如果var没有被声明, 那么就以$DEFAULT作为其值 *
${var:-DEFAULT} # 如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 *
${var=DEFAULT} # 如果var没有被声明, 那么就以$DEFAULT作为其值 *
${var:=DEFAULT} # 如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 *
${var+OTHER} # 如果var声明了, 那么其值就是$OTHER, 否则就为null字符串
${var:+OTHER} # 如果var被设置了, 那么其值就是$OTHER, 否则就为null字符串
${var?ERR_MSG} # 如果var没被声明, 那么就打印$ERR_MSG *
${var:?ERR_MSG} # 如果var没被设置, 那么就打印$ERR_MSG *
${!varprefix*} # 匹配之前所有以varprefix开头进行声明的变量
${!varprefix@} # 匹配之前所有以varprefix开头进行声明的变量
关于多重判断 ¶
[ -z "$pid_file" -a -z "$pid" ] && echo PID file not set
# $pid_file 变量为空,并且 $pid 变量为空时,整个表达式为真
# -a 为 AND 操作符,可以看到 -a 是整个优先级比较低的,会将其他部分算完之后,再进行计算
# -o 为 OR 操作符
评论
请登录后发表评论。
暂无评论。成为第一个评论者!