切换shell

显示当前shell
echo $SHELL
列出所有可用shell
chsh -l
切换shell,交互式输入要切换的shell
chsh
或直接指定要切换的shell
chsh -s /bin/bash

shell常用内部变量

  • $0就是该bash文件名
  • $n 传给脚本/函数的第n个参数
  • $?是上一指令的返回值
  • $$ 脚本的PID
  • $! 上一个被执行的命令的PID(后台运行的进程)
  • $# 传递给脚本/函数的参数个数
  • $*所有位置参数的内容:就是调用调用本bash shell的参数。
  • $@基本上与上面相同。只不过是
    • “$*”返回的是一个字符串,字符串中存在多个空格。
    • “$@”返回多个字符串。
  • $-当前Shell的工作状态

    常用的set命令

  • set -可以打开一个shell选项,set +关闭一个shell选项。

  • set -a 同set -o allexport,将当前变量导出,使得bash中运行的其他脚本也能够访问该变量,但与export不同的是只能访问,不能修改。
  • set -x 同set -o xtrace,当命令被执行时,打印出命令和参数。
  • set -n 同set -o noexec,读命令但不执行,常用于对脚本进行语法检查。
  • set -v 同set -o verbose,执行到哪一行就将那行内容打印出来。
  • set -u 同set -o nounset,对shell的变量替换作更加严格的限制,比如取用未定义的变量会报错。
  • set -e 同set -o errexit,在脚本执行过程中,如果有错误,就退出脚本,不再继续下去。

注意:如果设置了set -e,但脚本中又出现了可以允许失败的语句,可以在该语句后加|| true。
例如下面的例子,如果要复制的文件不存在,cp命令就会失败,这条语句返回值为非0,shell就会结束退出。但这句我们允许失败,希望继续执行下去,那就在这句后面加上 || true。这样即使前面的cp命令失败,或上true后返回永远为0,脚本就会继续执行。

  1. set -e
  2. cp -uv $F1_KEY_ADMIN_DIR/keys/* $CST_DIR/keys || true

shell if 参数

shell 编程中使用到得if语句内判断参数
–b 当file存在并且是块文件时返回真
-c 当file存在并且是字符文件时返回真
-d 当pathname存在并且是一个目录时返回真
-e 当pathname指定的文件或目录存在时返回真
-f 当file存在并且是正规文件时返回真
-g 当由pathname指定的文件或目录存在并且设置了SGID位时返回为真
-h 当file存在并且是符号链接文件时返回真,该选项在一些老系统上无效
-k 当由pathname指定的文件或目录存在并且设置了“粘滞”位时返回真
-p 当file存在并且是命令管道时返回为真
-r 当由pathname指定的文件或目录存在并且可读时返回为真
-s 当file存在文件大小大于0时返回真
-u 当由pathname指定的文件或目录存在并且设置了SUID位时返回真
-w 当由pathname指定的文件或目录存在并且可执行时返回真。一个目录为了它的内容被访问必然是可执行的。
-o 当由pathname指定的文件或目录存在并且被子当前进程的有效用户ID所指定的用户拥有时返回真。
UNIX Shell 里面比较字符写法:
-eq 等于
-ne 不等于
-gt 大于
-lt 小于
-le 小于等于
-ge 大于等于
-z 空串
= 两个字符相等
!= 两个字符不等
-n 非空串

变量加减乘除

shell里变量之间或数字之间进行加减乘除可以放在双括号里$((…))。只能计算整数,不支持浮点数。
t_diff=$(($t_now-$t_changed))
NRECORE_MINOR_VERSION="$((NRECORE_MINOR_VERSION+1))"

shift命令用法

shift命令用于对参数的移动(左移),通常用于在不知道传入参数个数的情况下依次遍历每个参数然后进行相应处理。
shift(shift 1) 命令每执行一次,变量的个数($#)减一(之前的$1变量被销毁,之后的$2就变成了$1),而变量值提前一位。
Shift 命令还有另外一个重要用途, Bash 定义了9个位置变量,从 $1 到 $9,这并不意味着用户在命令行只能使用9个参数,借助 shift 命令可以访问多于9个的参数。
Shift 命令一次移动参数的个数由其所带的参数指定。例如当 shell 程序处理完前九个命令行参数后,可以使用 shift 9 命令把 $10 移到 $1。

字符串截取

${#string} $string的长度
${string:position} 在$string中, 从位置$position开始提取子串
${string:position:length} 在$string中, 从位置$position开始提取长度为$length的子串
${string#substring} 从变量$string的开头, 删除最短匹配$substring的子串
${string##substring} 从变量$string的开头, 删除最长匹配$substring的子串
${string%substring} 从变量$string的结尾, 删除最短匹配$substring的子串
${string%%substring} 从变量$string的结尾, 删除最长匹配$substring的子串
${string/substring/replacement} 使用$replacement, 来代替第一个匹配的$substring
${string//substring/replacement} 使用$replacement, 代替所有匹配的$substring
${string/#substring/replacement} 如果$string的前缀匹配$substring, 那么就用$replacement来代替匹配到的$substring
${string/%substring/replacement} 如果$string的后缀匹配$substring, 那么就用$replacement来代替匹配到的$substring

说明:”* $substring”可以是一个正则表达式.

小贴士

用$()代替反单引号(`)

$()能够内嵌使用,而且避免了转义符的麻烦。

[]替代[]

使用[[]]能避免像异常的文件扩展名之类的问题,而且能带来很多语法上的改进,而且还增加了很多新功能:

操作符 功能说明
|| 逻辑or(仅双中括号里使用)
&& 逻辑and(仅双中括号里使用)
< 字符串比较(双中括号里不需要转移)
-lt 数字比较
= 字符串相等
== 以Globbing方式进行字符串比较(仅双中括号里使用,参考下文)
=~ 用正则表达式进行字符串比较(仅双中括号里使用,参考下文)
-n 非空字符串
-z 空字符串
-eq 数字相等
-ne 数字不等

set,env,export,source,exec区别

  • set设置了当前shell进程的本地变量,本地变量只在当前shell的进程内有效,不会被子进程继承和传递。
  • env仅为将要执行的子进程设置环境变量。
  • export将一个shell本地变量提升为当前shell进程的环境变量,从而被子进程自动继承,但是export的变量无法改变父进程的环境变量。
  • source运行脚本的时候,不会启用一个新的shell进程,而是在当前shell进程环境中运行脚本。
  • exec运行脚本或命令的时候,不会启用一个新的shell进程,并且exec后续的脚本内容不会得到执行,即当前shell进程结束了。

跳出循环

在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,像大多数编程语言一样,Shell也使用 break 和 continue 来跳出循环。

break命令

break命令允许跳出所有循环(终止执行后面的所有循环)。

  1. for prj in $projects; do
  2. build_project $prj
  3. if [ $? != 0 ]; then
  4. log() "$prj fail to compile"
  5. break
  6. fi
  7. done

在嵌套循环中,break 命令后面还可以跟一个整数,表示跳出第几层循环。例如:
break n
表示跳出第 n 层循环。

continue命令

continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。

终端里复制粘贴

选中文字,ctrl+shift,复制到剪贴板。
shift+insert,粘贴。