流程控制

和Java、PHP等语言不一样,sh的流程控制不可为空,如:

  1. <?php
  2. if (isset($_GET["q"])) {
  3. search(q);
  4. }
  5. else {
  6. //do nothing
  7. }

在sh/bash里可不能这么写,如果else分支没有语句执行,就不要写这个else。

还要注意,sh里的if [ $foo -eq 0 ],这个方括号跟Java/PHP里if后面的圆括号大不相同,它是一个可执行程序(和ls, grep一样),想不到吧?在CentOS上,它在/usr/bin目录下:

  1. ll /usr/bin/[
  2. -rwxr-xr-x. 1 root root 33408 6 22 2012 /usr/bin/[

正因为方括号在这里是一个可执行程序,方括号后面必须加空格,不能写成if [$foo -eq 0]

if else

if

  1. if condition
  2. then
  3. command1
  4. command2
  5. ...
  6. commandN
  7. fi

写成一行(适用于终端命令提示符):

  1. if `ps -ef | grep ssh`; then echo hello; fi

末尾的fi就是if倒过来拼写,后面还会遇到类似的

if else

  1. if condition
  2. then
  3. command1
  4. command2
  5. ...
  6. commandN
  7. else
  8. command
  9. fi

if else-if else

  1. if condition1
  2. then
  3. command1
  4. elif condition2
  5. command2
  6. else
  7. commandN
  8. fi

for while

for

在开篇的示例里演示过了:

  1. for var in item1 item2 ... itemN
  2. do
  3. command1
  4. command2
  5. ...
  6. commandN
  7. done

写成一行:

  1. for var in item1 item2 ... itemN; do command1; command2 done;

C风格的for

  1. for (( EXP1; EXP2; EXP3 ))
  2. do
  3. command1
  4. command2
  5. command3
  6. done

while

  1. while condition
  2. do
  3. command
  4. done

无限循环

  1. while :
  2. do
  3. command
  4. done

或者

  1. while true
  2. do
  3. command
  4. done

或者

  1. for (( ; ; ))

until

  1. until condition
  2. do
  3. command
  4. done

case

  1. case "${opt}" in
  2. "Install-Puppet-Server" )
  3. install_master $1
  4. exit
  5. ;;
  6. "Install-Puppet-Client" )
  7. install_client $1
  8. exit
  9. ;;
  10. "Config-Puppet-Server" )
  11. config_puppet_master
  12. exit
  13. ;;
  14. "Config-Puppet-Client" )
  15. config_puppet_client
  16. exit
  17. ;;
  18. "Exit" )
  19. exit
  20. ;;
  21. * ) echo "Bad option, please choose again"
  22. esac

case的语法和C family语言差别很大,它需要一个esac(就是case反过来)作为结束标记,每个case分支用右圆括号,用两个分号表示break