Linux shell 速学

来源:互联网 发布:经济学是什么 知乎 编辑:程序博客网 时间:2024/06/07 15:24

  • shebang
  • 变量
  • 比较和测试
  • 脚本调试

命令行界面或者shell环境的功能是使用户能与操作系统的内核(kernal)进行交互操作。shell script不过就是一些纯文本文件,我们能将一系列需要执行的命令行写入其中,然后通过shell来执行这些脚本。由于shell script都是利用shell与相关工具命令,所以不需要编译就可以执行。
其中bash(bourne again shell)是目前大多数GNU/Linux系统默认的shell环境,本文讨论的bash内容是在Centos环境下进行的。

shebang

shell脚本通常是一个以#!起始的文本文件,#!用来宣告这个script使用的shell名称。

#!/bin/bash

Linux任何环境下的任何脚本语言,都是以这样一个被称为shebang的特殊行作为起始的,它指明了执行这个脚本文件的解释程序。

 1. 如果脚本文件中没有#!这一行,那么它执行时会默认用当前Shell去解释这个脚本(即:$SHELL环境变量)。 2. 如果#!之后的解释程序是一个可执行文件,那么执行这个脚本时,它就会把文件名及其参数一起作为参数传给那个解释程序去执行。 3. 如果#!指定的解释程序没有可执行权限,则会报错“bad interpreter: Permission denied”。 如果#!指定的解释程序不是一个可执行文件,那么指定的解释程序会被忽略,转而交给当前的SHELL去执行这个脚本。 4. 如果#!指定的解释程序不存在,那么会报错“bad interpreter: No such file or directory”。 注意:#!之后的解释程序,需要写其绝对路径(如:#!/bin/bash),它是不会自动到$PATH中寻找解释器的。 5. 当然,如果你使用”bash test.sh”这样的命令来执行脚本,那么#!这一行将会被忽略掉,解释器当然是用命令行中显式指定的bash。

变量

脚本语言通常不需要在使用变量之前声明其类型,只需要直接赋值就可以了。在bash中,每一个变量的值都是字符串,无论给变量赋值时有没有使用引号,值都会以字符串的形式存储。变量名的命名须遵循如下规则:

首个字符必须为字母(a-z,A-Z)。中间不能有空格,可以使用下划线(_)。不能使用标点符号。不能使用bash里的关键字(可用help命令查看保留关键字)。

常用的变量类型大致可以分为如下几类,注意:变量名和等号之间不能有空格。
1. 本地变量
varname=value
本地变量只在创建它们的shell中可用。
2. 局部变量
local varname=value
局部变量只在当前代码段可用。
3. 环境变量
export varname=value
环境变量可以在创建它们的shell及其派生出来的任意子进程中使用。用env命令可以查看当前的环境变量。

 对于每个进程,在其运行时的环境变量可以使用下面的命令来查看: `cat /proc/$PID/environ` 其中,将PID设置成相关进程的进程ID。 `[develop@localhost shell]$ cat /proc/1058/environ  TERM=xtermHOME=/home/developSHELL=  /bin/bashUSER=developLOGNAME=developPATH=/usr/local/bin:/bin:/usr/bin`

4. 特殊变量

 $0:当前脚本的文件名 $num:num为从1开始的数字,$1是第一个参数,$2是第二个参数,${n}是第n个参数 $#:传入脚本的参数的个数 $*:所有的位置参数(作为单个字符串) $@:所有的位置参数(每个都作为独立的字符串)。 $?:当前shell进程中,上一个命令的返回值,如果上一个命令成功执行则$?的值为0,否则为其他非零值,常用做if语句条件 $$:当前shell进程的pid $!:后台运行的最后一个进程的pid $-:显示shell使用的当前选项 $_:之前命令的最后一个参数

比较和测试

  • 数值测试比较

    参数 说明 -eq 等于则为真 -ne 不等于则为真 -gt 大于则为真 -lt 小于则为真 -ge 大于或等于则为真 -le 小于或等于则为真
  • 文件系统相关测试

    参数 说明 [ -f $file_name ] 如果文件存在且为普通文件,则返回真 [ -x $var ] 如果变量var包含的文件存在且可执行,则返回真 [ -s $var ] 如果变量var包含的文件存在且至少有一个字符则为真 [ -d $var ] 如果变量var包含的文件是目录,则返回真 [ -e $var ] 如果变量var包含的文件存在,则返回真 [ -c $var ] 如果变量var包含的是一个字符设备文件的路径,则返回真 [ -b $var ] 如果变量var包含的是一个块设备文件的路径,则返回真 [ -w $var ] 如果变量var包含的文件可写,则返回真 [ -r $var ] 如果变量var包含的文件可读,则返回真 [ -L $var ] 如果变量var包含的是一个符号链接,则返回真
  • 字符串测试比较

    参数 说明 = 等于则为真 != 不相等则为真 -z 字符串 字符串的长度为零则为真 -n 字符串 字符串的长度不为零则为真

脚本调试

脚本调试的主要工作就是发现引发脚本错误的原因以及定位错误出现的具体位置。shell脚本中常见的调试方式有如下几种:

  • 通过echo方式
    在任何怀疑出错的位置打印出变量的值,这是最简单的一种调试技巧。

  • 通过选项方式

    • –n 此选项只做语法检查,而不执行脚本。
      sh -n test.sh
    • –c 该选项使Shell解析器从字符串而非文件中读取并执行命令,当需要调试一小段脚本的执行结果时,非常方便。
      bash -c 'x=5;y=3;let z=x+y;echo "z=$z"'
    • –v 该选项打印命令行的原始内容。
      bash -v test.sh
    • –x 该选项提供跟踪执行信息,将执行脚本的过程中把实际执行的每个命令显示出来,行首显示+,+后面显示经过替换之后的命令行内容,有助于分析实际执行的是什么命令。此选项是调试Shell脚本的强有力工具,是Shell脚本首选的调试手段。
      sh -x script.sh
      脚本开头提供参数:#!/bin/sh -x
      在脚本中用set命令启用or禁用参数:其中set -x表启用,set +x表禁用。
  • 通过test的方法
    利用test方法可以检查逻辑操作符,文件状态,字符串,数值测试!返回值0为真,其他任何值为假。

    [develop@localhost test]$ lstest.sh[develop@localhost test]$ [ 5 -lt 12 ][develop@localhost test]$ echo $?0[develop@localhost test]$ [ 5 -lt 3 ][develop@localhost test]$ echo $?1[develop@localhost test]$ [ -f test.sh ][develop@localhost test]$ echo $?0[develop@localhost test]$ [ -f script.sh ][develop@localhost test]$ echo $?1[develop@localhost test]$
  • 通过trap来调试
    trap用于捕获指定的信号并执行预定义的命令,语法为trap ‘command’ signal,其中signal是要捕获的信号,command是要执行的命令,捕获信号后所执行的命令, 可以是一条或多条合法的Shell语句,也可以是一个函数名,Shell脚本执行时,会产生三个伪信号(非操作系统产生,而仅是shell本身产生,称之为伪信息),通过使用trap捕获这三个伪信号并输出信息对调试大有帮助。

    SHELL三个伪信号
    EXIT 从一个函数中退出或整个执行完毕
    ERR 当一个命令执行不成功,返回非0状态时
    DEBUG 脚本中每一条命令执行之前

      1 #!/bin/bash  2   3 function testTrapErr()  4 {  5         echo "[Line:$1] Eorror: Command or function exited with status $?"  6 }  7 function foo()  8 {  9         return 1; 10 } 11  12 trap 'testTrapErr $LINENO' ERR 13 notExist 14 foo[develop@localhost test]$ sh test.sh test.sh: line 13: notExist: command not found[Line:13] Eorror: Command or function exited with status 127[Line:9] Eorror: Command or function exited with status 1[develop@localhost test]$

    note:可以用kill -l命令看到系统中全部可用的信号名

    1) SIGHUP   2) SIGINT   3) SIGQUIT  4) SIGILL   5) SIGTRAP6) SIGABRT  7) SIGBUS   8) SIGFPE   9) SIGKILL 10) SIGUSR111) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM16) SIGSTKFLT   17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP21) SIGTTIN 22) SIGTTOU 23) SIGURG  24) SIGXCPU 25) SIGXFSZ26) SIGVTALRM   27) SIGPROF 28) SIGWINCH    29) SIGIO   30) SIGPWR31) SIGSYS  34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+338) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+843) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+1348) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-1253) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-758) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-263) SIGRTMAX-1  64) SIGRTMAX    [develop@localhost test]$
  • 使用Bash专用调试器

    如果你在的脚本相当复杂且需要一个完整的像调试其他语言一样的调试器,那么可以使用bash专用调调试器,一个开源开源软件——bashdb。这个调试器很强大,有常用的诸多调试功能,如设置断点、单步跟踪、跳出函数等等。它的用户接口很像GDB,具体的操作可以参看相关文档 。

相关文章:
http://smilejay.com/2012/03/linux_shebang/
http://blog.csdn.net/jerry_1126/article/details/51526266

阅读全文
0 0
原创粉丝点击