AI智能
改变未来

Shell脚本中获取命令运行结果、特殊变量使用、条件判断等常用操作

文章目录

  • 前言
  • 获取命令执行结果
  • 使用反引号 “ ` “command “ ` “来执行命令
  • 使用括号组合 $(command) 来执行命令
  • 两种方式的区别
  • 特殊变量使用
    • $0 $1 $2 …
    • $$
    • $?
    • $#
    • $*
    • $@
    • 测试
    • `$*` 和 `$@` 的区别
  • 条件判断
    • `if` 语句格式
    • 中括号 `[]` 的作用
    • 具体条件
    • 文件判断
    • 数字判断
    • 字符串判断
    • 数字判断特殊写法
    • 逻辑关系运算符
  • 总结
  • 前言

    最近在处理一个

    Python

    局部变量的作用域问题时发现有些奇怪,想起了之前常写的

    Lua

    脚本,于是想写个函数测试一下,结果发现短短的十几行代码出现了多个错误,这可是我写了近三年的代码啊,才放下半年就记不清了,所以知识这个东西还是要不断“温故”,今天要总结的

    Shell

    脚本命令也是,基本属于一看就会,一写不对的状态,所以还是要把常用的操作总结到一起,方便查找和复习。

    获取命令执行结果

    脚本中常常要获取一些命令的执行结果,比如当前目录

    pwd

    、当前时间

    date

    等等,如果在控制台时直接输入后回车就能看到结果,但是在

    Shell

    脚本中却不能这样做,常见的有以下两种方式。

    使用反引号

    `

    command

    `

    来执行命令

    反引号就是键盘上

    Tab

    键上方的那个按键对应的符号,常写 Markdown 的小伙伴知道这个符号就是包裹代码块的那个符号,在

    Shell

    脚本中被用来执行命令得到结果,举个简单的例子

    #!/bin/bashresult=dateecho $resultresult=`date`echo $result

    将上述命令保存到文件

    cmd.sh

    中运行

    ./cmd.sh

    得到结果:

    $ ./cmd.shdateTue Jul 7 23:48:03 CST 2020

    从运行结果可以看出,如果不加反引号,我们常用的这些命令会被当成普通的字符串处理。

    使用括号组合 $(command) 来执行命令

    除了上面的反引号,使用美元符和小括号组合也可以在 Shell 脚本中运行命令,使用同样的例子测试

    #!/bin/bashresult=`date`echo $resultresult=$(date)echo $result

    保存到文件

    cmd.sh

    中运行

    ./cmd.sh

    得到结果:

    $ ./cmd.shTue Jul 7 23:53:27 CST 2020Tue Jul 7 23:53:27 CST 2020

    对比可以看出两种方式在这个命令下运行结果是一样的。

    两种方式的区别

    虽然上述两种方式都可以在

    Shell

    脚本中得到命令运行的结果,但是有一点是不一样的,那就是反引号执行命令不支持嵌套,不能实现反引号中再出现反引号,而

    $(command)

    的方式是支持嵌套的,关于这一点可以看下面这个例子。

    $ echo $(ls $(pwd))cmd.sh

    分析一下这个命令

    echo $(ls $(pwd))

    ,最里面的命令是

    $(pwd)

    先执行得到当前目录,然后执行命令

    $(ls 当前目录)

    得到目录下的文件,再通过

    echo

    命令把这个结果输出,就得到了

    cmd.sh

    这个文件名,因为我这个目录下只有这一个文件。

    系统的命令使用反引号的方式改写就不生效了。

    $ echo `ls `pwd``cmd.shpwd

    我们还是仿照上面嵌套来写,但是

    echo

    后面的内容其实被分成了3部分,一个

    ls

    命令,一个

    pwd

    字符串、一个空命令,这样就能解释运行结果

    cmd.shpwd

    了。

    对照着结果我们就可以知道了,

    $(command)

    的方式更加强大,可以支持命令的嵌套,应用更广泛一点,而反引号的方式跟多出现在之前的脚本中。

    特殊变量使用

    从学习语言的第一天起就记住了变量名中只能有数字、字母、下划线,并且数字不能打头(Shell中只能字母开头),但是在

    Shell

    脚本中有一些特殊的变量,包含各种奇奇怪怪的符号。

    $0 $1 $2 …

    这些是运行

    Shell

    脚本时传递给脚本的命令行参数。命令行参数用 $n 表示,$0表示当前脚本的文件名,$1 表示第一个参数,$2 表示第二个参数,依次类推,可以类比 Windows 下的

    %0

    %1

    %2

    $$

    当前

    Shell

    脚本的进程ID。如果在命令行执行得到的是当前

    bash

    的进程ID,如果放到脚本中,得到的是脚本的进程ID。

    $?

    可以获取上一个命令执行后的返回结果。

    $#

    传递给脚本的命令行参数的个数。

    $*

    传递给脚本的命令行参数的所有参数。

    $@

    传递给脚本的命令行参数的所有参数,与

    $*

    稍有不同。

    测试

    写个脚本测试一下,新建

    cmdargs.sh

    文件,编写下面代码:

    #!/bin/bashecho \\$0 is $0echo \\$1 is $1echo \\$2 is $2echo \\$$ is $$echo \\$# is $#echo \\$* is $*echo \\$@ is $@

    先执行

    ./cmdargs.sh

    脚本, 然后输出

    $?

    脚本的退出状态,运行结果如下:

    $ ./cmdargs.sh I love my daughter$0 is ./cmdargs.sh$1 is I$2 is love$$ is 197$# is 4$* is I love my daughter$@ is I love my daughter$ echo $?0

    $*

    $@

    的区别

    对照这个源码和输出结果,这些特殊变量应该可以分清楚了,其中

    $*

    $@

    都是把所有内容都列出来了,但它俩还是有点区别的,当这两个变量都被双引号包裹时,通过

    for

    循环会得到不同结果,写个脚本

    cmdargs2.sh

    试一下

    #!/bin/bashecho \"test for \\\"\\$*\\\"\"for var in \"$*\"doecho \"$var\"doneecho \"test for \\\"\\$@\\\"\"for var in \"$@\"doecho \"$var\"done

    运行结果如下,

    \"$*\"

    把所有的参数当成了一个整体,而

    \"$@\"

    把各个参数都拆分开了,可以通过循环依次打印出来。

    $ ./cmdargs2.sh I love my daughtertest for \"$*\"I love my daughtertest for \"$@\"Ilovemydaughter

    条件判断

    说起条件判断第一反应就是

    if

    了,在

    Shell

    脚本中也有

    if

    语句,同样是条件判断的中坚力量,先来看看

    if

    语句的写法:

    if

    语句格式

    if [ -d $filename ]; thenecho \"this is a directory.\"elif [ -a $filename ]; thenecho \"the file is exist.\"elseecho \"the file is not exist.\"fi

    直接提供一个最复杂的情况,如果不需要

    elif

    或者

    else

    分支,直接删掉就可以,但是

    if

    then

    fi

    这些都是必须的,并且中括号里面的表达式与中括号之间都要有空格,如果挨着写会报错的。

    中括号

    []

    的作用

    一度认为

    if

    条件语句就是这样写,中括号

    []

    应该是语法的一部分,但是查询后发现这居然是一个命令,和

    ls

    pwd

    一样是一个可以执行命令,放在

    if

    条件判断时基本等同于

    test

    命令。

    $ which [/usr/bin/[$ which test/usr/bin/test

    看着这个查询结果感觉神奇吧,此外还有一个

    [[]]

    双中括号的操作,这个就不是命令了,而是

    Shell

    的一个关键字,比

    []

    要强大的多。

    具体条件

    Shell

    脚本最常见的条件就是文件判断,数字判断和字符串判断了,接下来列举一下这些判断的常见写法。

    文件判断

    命令 含义
    -a $filename 文件存在时为真
    -d $filename 文件名对应的是目录时为真
    -s $filename 文件非空时为真
    -r $filename 文件可读时为真
    -w $filename 文件可写时为真
    -x $filename 文件可执行时为真

    数字判断

    命令 含义
    n1 -eq n2 n1等于n2时为真
    n1 -ne n2 n1不等n2时为真
    n1 -gt n2 n1大于n2时为真
    n1 -lt n2 n1小于n2时为真
    n1 -ge n2 n1大于等于n2时为真
    n1 -le n2 n1小于等于n2时为真

    字符串判断

    命令 含义
    -n str1 str1字符串不为空串时值为真
    -z str1 str1字符串为空串时值为真
    str1 == str2 str1与str2相等时为真
    str1 != str2 str1与str2不等时为真
    str1 > str2 按字典序str1排在str2后面时为真
    str1 < str2 按字典序str1排在str2前面时为真

    数字判断特殊写法

    命令 含义
    ((\"$n1\" == \"$n2\"))
    n1等于n2时为真
    ((\"$n1\" != \"$n2\"))
    n1不等n2时为真
    ((\"$n1\" > \"$n2\"))
    n1大于n2时为真
    ((\"$n1\" < \"$n2\"))
    n1小于n2时为真
    ((\"$n1\" >= \"$n2\"))
    n1大于等于n2时为真
    ((\"$n1\" <= \"$n2\"))
    n1小于等于n2时为真

    逻辑关系运算符

    命令 含义
    -a 与操作,用于

    []

    test

    操作符

    -o 或操作,用于

    []

    test

    操作符

    取反操作,用于

    []

    test

    操作符 和

    [[]]

    关键字

    && 与操作,用于

    [[]]

    关键字

    || 或操作,用于

    [[]]

    关键字

    这些逻辑写法千奇百怪的,写两个例子就慢慢就慢慢理解了,比如判断一个字符串不为空,并且这个字符串指定的目录还存在就可以写成

    if [ -n \"$1\" -a -d \"$1\" ]; thenecho $1 directory is existfi

    使用双小括号来比较数值变量,写在双小括号中的变量前面可以不加

    $

    符号,还有诸多特权等着你去发现

    num1=$1num2=$2if (( num1 > num2)); thenecho num1 \\> num2fi

    总之在学习这些条件比较的时候踩了不少坑,有很多情况都没有注意到,不过慢慢也适应了这种语法,但还是免不了会出现一个小问题,这里提供一个

    Shell

    语法检查的在线网站 《shellcheck》,将要检查的脚本放到页面上检测,会给出详细的错误信息,当然也有命令版本,可以自己到对应的 github 页面上下载哦~

    总结

    • Shell

      脚本中获取命令的执行结果,可以通过反引号

      `

      command

      `

      ,或者小括号

      $(command)

      的方式得到

    • Shell

      脚本中有一系列

      $

      开头的变量,用好他们是脚本和函数传递参数的关键

    • Shell

      脚本中的条件判断对于初学者来说很头大,有许多注意的点要记住,判断形式也多种多样

    • 脚本中有单引号、双引号、反引号,简单来记就是单引号中原样输出,双引号中变量求值后输出,反引号中只能写需要执行的命令
    • 脚本中还要中括号、双中括号、小括号、双小括号等,上面都提到过,可以自己练习下,具体的细节怕是要单独总结了,放到一起太多了
    • 脚本的中的分号起到语句结束的作用,如果有换行就不需要分号了,比如
      if

      条件后面的

      then

      如果换行,那么

      then

      前面的分号可以省略

    • 再记住一个坑,脚本赋值等号两端不能有空格,脚本判断等号两端必须有空格

    ==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==

    有些局,选择不入便立于不败之地,选择介入,即使曾身经百战,也恐难全身而退,更不要谈什么收益了~

    赞(0) 打赏
    未经允许不得转载:爱站程序员基地 » Shell脚本中获取命令运行结果、特殊变量使用、条件判断等常用操作