Skip to content
On this page

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

参考