资料推荐

常见命令

  • man: 玩Linux系统需要知道的第一条命令,可以自救。如man bash可以查看bash的基础知识。
  • help: 查询shell builtin命令手册。在ubuntu下输入help命令可查看详细介绍。
  • grep
  • sed
  • awk

sh与bash的区别

  • sh (Bourne Shell) 是Unix系统下最流行的shell之一。

  • bash (Bourne Again Shell) 是Linux系统下默认的shell

  • bash是sh的一个超集,bash兼容sh,同时增加了一些新特性。

    • history: 查询历史命令。
    • alias: 设置命令别名。
    • 目录操作命令,如pushdpopd
    • 任务管理命令,如bg, fg, Ctrl-Z等。
    • 数组类型。
    • 参数展开(Parameter Expansion)。如${parameter}, ${parameter:+word}, ${parameter:offset:length}等。
    • 算术展开(Arithmetic Expansion)。如num=1; ((num++));
    • 新的built-in命令。

那些坑爹的括号

  • [][[]] 的区别

    • 两者都是test命令,用于检查表达式的真值性。若表达式为true,则返回0,否则返回1.
    • [[]]是bash对[]的改进,bash同时支持两者,而sh只支持[]bash脚本中始终使用[[]]即可
    • 两者都能执行逻辑与、逻辑或运算,但写法不同,[]-a-o[[]]&&||来表示。
    • [] 不能执行正则匹配,[[]]可以执行正则匹配。如[[ $name =~ abc* ]][[ $name == [Tt]om ]]
    • 在没有加引号并且变量含有空格时,[]会展开为多个单词,[[]]则不会展开。
    name="Guo Jing"
    if [ -z $name ]    # error.    # error! You must quote the string with spaces in `[]`
    if [[ -z $name ]]  # ok.
    
  • ()(()) 的区别

    • 两者的作用完全不同。()用于命令替换、将多条命令组在一起,(())用于算数运算。
    • () 和反引号都可用来命令替换,但前者在嵌套命令时写法更简单,因此一般建议使用前者。
    today=$(date)    # 命令date的输出结果会保存在today变量中,这便叫「命令替换」。
    
    path="/home/minieye/work/ft4"
    parent=$(basename $(dirname $path))  # 嵌套命令,不需对$转义,写法简单
    parent=`basename \`dirname $path\``  # 嵌套命令,需要对反引号转义,写法麻烦
    
    (ls; date; pwd) > /tmp/log   # 使用圆括号将多条命令组在一起。/tmp/log的内容为3条命令的执行结果。
    
    if (( $# != 1 )); then echo "Invalid input"; fi    # 双圆括号用于执行算数运算
    for (( i=1; i<10; i++ )); do echo $i; done
    
  • [[]](()) 的区别

    • 只需记住[[]]用于字符串相关的表达式,(())用于数字相关的表达式。
    • 特别注意,千万不要在[[]]中用大于/小于号比较数字,否则可能会踩坑。
    if [[ 12 < 2 ]]; then echo what the hell; fi   # if语句会返回true,因为`[[]]`比较的是12和2的字典序大小,在字典序中12排在2前面。
    
  • (){}的区别

    • ()用于命令替换,{}则用于参数替换。
    • 「命令替换」是指将命令执行的结果返回,如$(date)返回date命令的执行结果。
    • 「参数替换」是指将参数或变量的值返回,如假设name="minieye",则${name}返回变量name的值"minieye"。 这是参数替换最简单的例子,参数替换还有很多灵活的玩法,比如${name:1:2}返回变量name的字符串"am"。