迥异的Linux Shell Script

发布说明

  • 2024年09月,更新说明为什么Linux Shell(准确的说,应该是Shell或Unix Shell)会显得“迥异”
  • 2009年,初次发布

摘要:如果你已经习惯编写Shell脚本,那么一切都显得很自然了。但像我这样,之前已经习惯了C语言(风格)的编程,就觉得Shell并不是那么友好。这里将记录一些Shell和”C风格”迥异的地方,以供参考。本文测试环境:GNU bash, version 3.00.15(1)-release (i386-redhat-linux-gnu)。文章中很多实例直接来在参考文件[1]、[2]。

Linux

1、变量定义等号两边不能有空格

#!/bin/bash
myvar=3 #正确
myvar = 3; #等号边多了空格,是错误的!很迥异
1.1、还是空格,这次是不能没有
#!/bin/sh
myVar="OFF"
if [   $myVar = 'OFF'    ];then  
#这里[]中括起来的内容两端必须有空格,if [$myVar = 'OFF']是不能正常工作的。也很迥异吧
#注意 if 和 [ 之间也是有空格的!
        echo "works"
else
        echo "Not works"
fi

2、双引号和单引号

testvar=5
myvar='Haha$test' #shell会解释$test
myvar2="Haha$test" #shell会解释$test
echo $myvar $myvar2 #输出:Haha$test Haha5

双引号中的字符如果有变量,shell会尝试解释它,单引号中不会。所以,如果字符串中没有要解释的变量尽量使用单引号,据说速度会快些。

这个到不算很迥异,还有很多其他的语言也都有这样的约定。

3、奇怪的算术运算

shell中算术运算需要使用$((和))将算术运算括起来

$(( $myvar + 12 )) #这个非常迥异

4、case语句

case "${x##*.}" in
      gz)
            gzunpack ${SROOT}/${x}
            ;;
      bz2)
            bz2unpack ${SROOT}/${x}
            ;;
      *)
            echo "Archive format not recognized."
            exit
            ;;
esac           #这个比较迥异 "esac"、";;"、"bz2)"

5、函数中的变量作用范围

#!/usr/bin/env bash 
myvar="hello" 
myfunc() {
     myvar="one two three"
     for x in $myvar
     do
         echo $x
     done
} 
myfunc 
echo $myvar $x
输出:
one
two
three
one two three three  #函数myfunc中的变量,在函数之外仍然存在。
#你可以通过关键字 local 限制变量只在函数中有效果 #这个比较迥异

还有更迥异的吗?

为什么Linux Shell会显得迥异

更新于202409月:这篇文章最初写于2009年,因为工作中需要非常多的使用Linux Shell(其实是Bash),当时刚刚开始较为深入的使用一些Bash的特性。如果,你和我一样,在深入Linux Shell之前,曾学过一些高级语言,那么再来使用Shell是很容易觉得Shell很迥异的,现在想想,原因大概如下:

  • Shell(或者Bash)是用户与Linux内核直接打交道的一个“接口”,所以在使用上,它与很多Linux底层特性有关,例如很多概念与Posix标准类似,例如标准输出、标准输入等。
  • Shell是一个比较“底层”的工具,与各种“高级语言”不同,各种“高级语言”通常会在发展中,尝试兼容一些语言上的“自然”表现,所以,“高级语言”会更自然一些
  • Shell发展非常早,我这篇文章标题是“Linux Shell”,而事实上,Shell是远远早于Linux的。最早的Thompson shell发布与1971年,即便是现在最为广泛使用Bash也是最早发布于1989年,而Linux则是于1991年发布。为了保持向后的兼容性,所以越早发布的语言,则会保持越多“历史积累”的特性。

参考文献:

  1. http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-1/index.html
  2. http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/index.html
  3. http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-3/index.html
  4. http://www.linuxsir.org/main/?q=node/135
  5. BASH Programming − Introduction HOW−TO

7 responses to “迥异的Linux Shell Script”

  1. 双引号那个,倒是在php里面也有吧。复杂的任务别用bash了,用perl或者Python吧。

  2. 补充一个:
    变量在初始化、赋值的时候,不需$;在使用该变量的时候则需要加$符号

    myvar=4
    echo $myvar
    #比较迥异,还有什么语言变量在初始化和使用的时候会不一样的?

  3. 还是Perl好,Shell脚本看还好写要命啊……

  4. admin

    算术运算还可以写为:expr $i + 1 仍然要注意加号两边的空格

  5. gary

    我一段时间不写shell,就忘记了许多语法了. 所以现在一般拿旧的脚本来改.
    至于perl,熟悉的人写得随心所欲,不熟悉的人看得头大.
    2.关于双引号,和单引号,是针对逃逸字符来说有个区别的.单引号忽略所有特殊字符,双引号三种特殊字符不被忽略:$,\,`
    3.奇怪的算术运算里的$((和))将算术运算括起来,是bash shell才有的,好像.我也觉得怪异.

  6. 算术运算还可以这样写
    let a=a+2;
    加号两边可不用空格

  7. black_pho

    #!/usr/bin/env bash
    myvar=”hello”
    myfunc() {
    myvar=”one two three”
    for x in $myvar
    do
    echo $x
    done
    echo $$
    }
    myfunc
    echo $myvar $x
    echo $$

    // 执行结果one
    two
    three
    1782
    one two three three
    1782
    可以看到它们在同一个进程1782中,就是当前shell下,所以$mayvar的值
    被后面的覆盖了。

Leave a Reply

Your email address will not be published. Required fields are marked *