shell脚本中获取执⾏系统命令的输出结果
这个主要介绍的⽅法是获取命令的输出内容,⽽不是命令执⾏成功与否的返回值。
通常情况下,在shell脚本中需要获取命令的输出内容,然后根据输出内容判断下⼀步的执⾏操作。
⽐较常⽤的⼀种⽅式就是, 匹配命令输出的内容中是否存在某些关键字,选择执⾏的不同动作。
⽐较常⽤的⼀种⽅式就是采⽤反向单引号的⽅式 --  保存结果的变量名=`需要执⾏的linux命令`
这种⽅式在使⽤时,有些细节的地⽅需要注意。 先⽤⼏个例⼦来说明⼀下。
⽐如在CentOS7环境中,使⽤rpm -qa命令查询某些rpm包是否安装,没有安装的话进⾏安装操作。
举个简单的例⼦来说:
#!/bin/bash
check_results=`rpm -qa | grep "zlib"`
echo "command(rpm -qa) results are: $check_results"
if [[ $check_results =~ "zlib" ]]
then
echo "package zlib has already installed. "
else
echo "This is going to install package zlib"
fi
保存为test.sh⽂件,然后运⾏
$bash test.sh
结果为:
command(rpm -qa) results are: zlib-1.2.7-13.el7.x86_64
package zlib has already installed.
shell脚本返回执行结果
这个脚本基本上是可以⼯作的。
那么,我们同样使⽤类似的⽅式来检查iscsi-initiator软件包是否安装。 与上⼀个命令不同的是,这个命令是否安装不能通过rpm -qa命令获取。
我们采取另⼀种⽅式
#!/bin/bash
check_results=`iscsiadm --version | grep iscsiadm`
echo "check command(iscsiadm) available results are: $check_results"
if [[ $check_results =~ "iscsiadm" ]]
then
echo "command iscsiadm could be used already."
else
echo "command iscsiadm can't be used. Install it"
rpm -ivh iscsi-initiator-utils-6.2.0.873-29.el7.x86_64.rpm
fi
执⾏的结果为:
$ bash test.sh
check command(iscsiadm) available results are: iscsiadm version 6.2.0.873-28
command iscsiadm could be used already.
这时候看起来脚本是⼯作正常的,显⽰iscsiadm已经可⽤。那么假如⼀开始的时候iscsiadm命令不可⽤呢?
我们可以将上⾯的check_results=`iscsiadm --version | grep iscsiadm`改成为check_results=`iscsiadmm --version | grep iscsiadm`
这样我们故意将命令写错,模拟命令没有安装的情况下脚本的运⾏。
修过后执⾏结果如下
$ bash test.sh
test.sh: line 2: iscsiadmm: command not found
check command(iscsiadm) available results are:
command iscsiadm can't be used. Install it
看起来好像也是⼯作正常的,但是为什么check_results的内容为空呢? 难道不应该将“command not found: iscsiadmm”内容赋值给check_results,然后打印显⽰出来吗?
我们将iscsiadmm --version | grep iscsiadm单独在命令⾏中执⾏,也是有输出的啊,为什么不能赋值成功呢?
这个时候如果我们在命令执⾏完毕之后,执⾏命令echo$? 这个时候得到的值为127(Centos7系统)。在命令⾏中单独执⾏scsiadm --version | grep iscsiadm命令之后,执⾏echo $?得到的值为0(Centos7系统)
从这⾥可以看出在使⽤··(2个反向单引号)的⽅式获取执⾏结果时需要保证单引号内的命令是可以执⾏成功的。
就算是这样就能保证我们可以获取到想要的内容吗? 不⼀定,再来看个例⼦。
#!/bin/bash
check_results=`java -version`
echo "check java version results are: $check_results"
if [[ $check_results =~ "1.8." ]]
then
echo "java version is 1.8, it seems not need to install java again."
else
echo "It is going to install jdk 1.8 version"
fi
执⾏结果为:
$ bash test.sh
java version "1.8.0_73"
Java(TM) SE Runtime Environment (build 1.8.0_73-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.73-b02, mixed mode)
check java version results are:
It is going to install jdk 1.8 version
怎么回事?命令jdk已经安装了,为什么还是没有匹配到呢?根据第⼆个例⼦,我们⼿动执⾏命令 java -version 然后执⾏命令$? 得到的结果为0, 说明命令是执⾏成功的。怎么还是没有获取到命令的输出呢?
这个现象出现的原因是有可能命令的执⾏结果被重定向了。
试着将check_results=`java -version` 改成check_results=`java -version 1> /dev/stdout` 和 check_results=`java -version 2>
/
dev/sdtout` 看看输出是否有变化
为了防⽌这种情况的发⽣,最终我们将上⾯改成check_results=`java -version 2>&1` 这样得到了想要的结果。
使⽤  保存结果的变量名=`需要执⾏的linux命令` 这种⽅式来获取命令的输出时,注意的情况总结如下:
1)保证反单引号内的命令执⾏时成功的,也就是所命令执⾏后$?的输出必须是0,否则获取不到命令的输出
2)即便是命令的返回值是0,也需要保证结果是通过标准输出来输出的,⽽不是标准错误输出,否则需要重定向
因此我们推荐使⽤  保存结果的变量名=`需要执⾏的linux命令 2>&1 `的⽅式来获取命令的执⾏结果。
感兴趣的朋友可以试下第⼆个例⼦中改成  check_results=`iscsiadmm --version 2>&1`的结果。
此外还有⼀种获取命令执⾏返回值的⽅式 变量名=$(需要执⾏的命令) 对于这种⽅式没有进⾏测试,所以不再此讨论。对于上⾯提到的获取命令执⾏输出的情况,和获取函数执⾏结果的⽅式并不同,请在使⽤中进⾏注意。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。