Appearance
shell 是一个脚本语言,通过解释器来执行,可以是交互式的也可以是批处理的方式。 shell 是用户与 Unix 沟通的桥梁,用户通过 shell 调用系统的大部分功能。
什么是 shell
shell 是一个脚本语言,通过解释器来执行,可以是交互式的也可以是批处理的方式。 shell 是用户与 Unix 沟通的桥梁,用户通过 shell 调用系统的大部分功能。 几种常见的解释器: bash: Linux 默认的 shell sh: Unix 默认的 shell zsh: 兼容 bash 的'终极'终端 其他的还有:ash, csh, tcsh, ksh
变量
局部变量、环境变量、shell 变量
sh
myName="kse" # 等号两边不能有空格
readonly myName # 这样 myName 就是只读的了
myNumber=42
echo $myName
echo ${myNumber} # 推荐 变量名统一用大括号包裹
unset myNumber # 删除变量;但是不能删除只读变量
特殊变量
变量 | 含义 |
---|---|
$0 | 当前脚本的文件名 |
$n | 第n个参数 |
$# | 参数数量 |
$* | 所有参数(被""包裹时把所有参数作为一个整体返回) |
$@ | 所有参数 |
$? | 上个命令的退出状态/函数的返回值 |
$$ | shell pid |
替换
支持的转义字符:
sh
echo '\\, \a, \b, \f, \n, \r, \t, \v'
命令替换使用反引号包裹:
sh
now=`date`
echo ${now}
变量替换:
sh
myName='kse'
echo ${myName}
echo ${myName:-"name not set"}
echo ${myName:+"name set but still use this"}
echo ${myName:="name not set and set myName"}
echo ${myName:?"if name not set then send this message and break"}
运算符
算数运算符
原生 bash 不支持算数运算符,需要借助 expr 来完成简单计算。
sh
echo `expr 1 + 2` # 乘法需要使用 \*
if [ 1 == 1 ] # 这里的空格是必须的
then
echo 'is true'
fi
关系运算符and布尔运算符
sh
## -eq, -ne, -gt, -lt, -ge, -le, -o, -a
if [ 1 -eq 2 ]
then
echo "1==2"
else
echo "1!=2"
fi
字符串运算符
sh
## =, !=, -z, -n, str
if [ "hello" ]
then
echo "not empty"
else
echo "is empty"
fi
文件测试运算符
sh
file="/Users/keng42/Desktop/shell.md"
if [ -s $file ]
then
echo "file size bigger than 0"
fi
操作符 | 说明 |
---|---|
-d file | 是目录 |
-f file | 是普通文件(既不是目录,也不是设备文件) |
-r file | 可读 |
-w file | 可写 |
-x file | 可执行 |
-s file | 文件大小大于0 |
-e file | 文件或目录是否存在 |
-b file | 是块设备文件 |
-c file | 是字符设备文件 |
-g file | 设置了 SGID 位 |
-k file | 设置了粘着位(Sticky Bit) |
-p file | 是具名管道 |
-u file | 设置了 SUID 位 |
字符串
单引号:原样输出
双引号:支持替换
sh
myName='kse'
greeting='hello '${myName}' !'
greeting2='hello !'
echo ${#myName} # 字符串长度
echo ${greeting}
echo ${greeting2}
echo ${myName:2:1} # 获取子字符串 e
echo `expr index "${myName}" s` # 查找子字符,下标从1开始
数组
sh
arr=(1 2 3 4)
echo ${arr[1]} # 下标从1开始
echo ${#arr}
echo ${arr[*]}
分支
sh
op='times'
case ${op} in
'add') echo 'add'
;; # 相当于 break
'times') echo 'times'
;;
*) echo 'others'
;;
esac
if [ ${op} = 'times' ]
then
echo 'times'
elif [ ${op} = 'add' ]
then
echo 'add'
else
echo 'others'
fi
循环
sh
for f in ${HOME}/.zsh*; do
echo $f
done
while read txt; do
echo "hello ${txt}"
done
函数
sh
function sayHi() { # function 不是必需的
echo "hi $1 $2"
return 2 # 只能返回数字
}
sayHi 'kse' 'lee' # 直接输入函数名即可调用
ret=$? # 只能通过这种方式获取函数的返回值
echo ${ret}
IO 重定向
导入
sh
. filename
source filename # 两种方式都可以,一般使用第一种
批量重命名文件
sh
index=1
for f in ~/Desktop/48/*.gif; do
if [[ index -le 9 ]]; then
name='0'$index'.gif'
else
name=$index'.gif'
fi
`mv ${f} $HOME'/Desktop/48/'${name}`
index=`expr $index + 1`
done