Shell 基本知识

January 15, 2014 posted in [basic shell]

计算机语言是相通的,但是却各有特点。很多时候我们了解了一门语言后大呼“哦,原来是这么回事儿”,事后又忘记了。当再次遇到问题,或者搁置一段时间后想要再次上手仍然显得困难。因此,我打算对每种语言(shell,python,javascript,php)总结一些基本的概念和知识。主要是从基本概念和特点、变量、基本类型及作用域、函数定义、判断及循环着手吧。

shell基本概念和特点

shell脚本中一切皆是命令,是一堆命令的集合。 shell脚本很有意思,和一般的编程语言很不一样,每句话都是可以在命令行中运行的,是一系列命令的组合。一些有意思的例子

  1. 括号(), 在shell中表示在子shell中执行;
  2. shell函数中的return(return表示退出码,不是普通意义的返回值?为什么,因为shell是一堆命令的集合,函数也只是将一组命令打包命名,shell中使用管道的概念,即对输出进行重定向;
  3. 令人混淆的空格问题。刚开始写shell的时候一定很不理解为什么shell中赋值、判断中空格显得很怪异。其实根本原因在于shell全部是命令的集合,而命令与选项之间需要空格。我们来剖析一下: a=1a = 1怎么被解析,因为命令和选项由空格隔开,前面一句没有空格,命令是"a=1",解析到了=号,所以认为是赋值命令,参数由等号前后决定。后面的a = 1被解析为命令是a,参数是等号和1,而a是没有被定义的,所以发生了错误。从这里我们可以充分理解一切都是命令了吧。 再来看if中的条件判断,其实[也是一条命令,相当于test,只不过[的最后一个参数必须是]来表示结束,命令的写法就是命令+空格+参数+空格,所以命令[的写法就是[+空格+若干参数+],所以如果[和参数之间没有空格,就会认为命令是]+参数,显然没有这样的命令,所以又会出错

变量、基本类型及作用域

$varname表示变量,是${varname} 的一个缩写。赋值使用varname=$val shell中变量类型概念很弱,普通的都当做字符串来处理。用 $(())可以表示整数操作, let也可以进行计算, 例如 a=$((b+1)), echo $((b++)), echo $((--b))。shell中也有数组,可以用小括号加空格来赋值,引用数组变量要用 ${var[index]},index为/@的时候表示所有元素, 个数用 ${#var[*]},可以用 for var in ${arr[]}或者while进行遍历,清空单个用空赋值,unset清空所有。 变量的作用域为shell进程,函数的意义决定了没有函数作用域,用export可以扩大变量作用域

函数定义

再次强调,函数其实是命令的集合,也是一个命令,所以调用方式是 functname param1 param2 ... 而不是 functname(param1, param2, ...) 函数定义:

function functname { 
    shell commands 
} 
或者
functname() {

}

我们可以在脚本中来获取参数的值。使用$N,其中$0是函数名称,$1为param1,$2为param2,如此类推,如果N大于实际参数的数目,为空。我们一般将位置变量是从$1开始。 $* 表示所有参数组成的一个字符串,这些参数之间的间隔是IFS的首个字母即空格,IFS包括TAB,空格,换行等字符。 $@ 等同于"$1" "$2"... "$N"。 $# 表示参数的个数 $? 退出码

流程控制

  1. shell命令,可以按照分号分割,也可以按照换行符分割。如果想一行写入多个命令,可以通过“';”分割。
  2. if语句结构[if/then/elif/else/fi]
  3. for循环使用方法(for/do/done): for … in 语句, for((赋值;条件;运算语句))
  4. while循环使用(while/do/done)
  5. untile循环使用(untile/do/done)
  6. case选择语句使用(case/esac),用两个分号表示break, 其中pattern是正则表达式,* 任意字串;? 任意字元;[abc]表示a, b, 或c三字元其中之一;[a-n] 从a到n的任一字元;|表示多重选择
  7. select语句使用方法(产生菜单选择), 使用(select name in seq/do/case $ch in/esac/done)

有了以上的基础,一些基本的脚本程序就可以搞定了。其他的遇到问题再查资料吧。