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.

这个脚本基本上是可以工作的。

那么,我们同样使用类似的方式来检查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`的结果。

此外还有一种获取命令执行返回值的方式 变量名=$(需要执行的命令) 对于这种方式没有进行测试,所以不再此讨论。

对于上面提到的获取命令执行输出的情况,和获取函数执行结果的方式并不同,请在使用中进行注意。

到此这篇关于shell 脚本中获取命令的输出的实现示例的文章就介绍到这了,更多相关shell 脚本中获取命令输出内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android shell命令行中过滤adb logcat输出的几种方法

    我们在Android开发中总能看到程序的log日志内容充满了屏幕,而真正对开发者有意义的信息被淹没在洪流之中,让开发者无所适从,严重影响开发效率.本文就具体介绍几种在shell命令行中过滤adb logcat输出的方法.        1.只显示需要的输出(白名单) 最方便的当然是通过管道使用 grep 过滤了,这样可以使用 grep 强大的正则表达式匹配.简单的匹配一行当中的某个字符串,例如 MyApp: adb logcat | grep MyApp adb logcat | grep -i

  • 神奇的shell命令行输入与输出功能介绍

    标准输入/输出和重定向,Linux发行版Fedora Core Linux,而Red Hat公司原来Red Hat Linux的开发团队也将继续参与这一发行版本的开发工作. 标准输入与输出 我们知道,执行一个shell命令行时通常会自动打开三个标准文件,即标准输入文件(stdin),通常对应终端的键盘:标准输出文件(stdout)和标准错误输出文件(stderr),这两个文件都对应终端的屏幕.进程将从标准输入文件中得到输入数据,将正常输出数据输出到标准输出文件,而将错误信息送到标准错误文件中.

  • shell(bash)下“time” 命令的输出详解

    前言 相信大家都知道bash下time是一个很有用的命令,它可以为一段脚本或一个程序的执行计时,这通常在粗略比较程序执行效率的时候很方便.但是你会发现,time命令输出的时间文字不能被简单地重定向,例如重定向至一个文本文件,只能显示在屏幕上,这对于非交互计时很不方便. 例如: $ time find . -name "mysql.sh" >1.txt real 0m0.081s user 0m0.060s sys 0m0.020s $ time find . -name &quo

  • 用shell命令读取与输出数据的代码

    shell脚本读取数据有以下几种方式:1.键盘输入,默认2.从文件中读取3.通过管道命令传递 echo的功能:\c :不换行\f :进纸\t :跳格\n :换行\表示转义,例如:"\"/dev/rmt0"\"翻译为,"/dev/rmt0" read:从键盘或文件的某一行文本中读取信息,并将其赋给一个变量. 复制代码 代码如下: [jb51]/>read namehello i am a regular user[jb51]/>echo

  • Android shell命令行中过滤adb logcat输出的方法

    我们在Android开发中总能看到程序的log日志内容充满了屏幕,而真正对开发者有意义的信息被淹没在洪流之中,让开发者无所适从,严重影响开发效率.本文就具体介绍几种在shell命令行中过滤adb logcat输出的方法.        1.只显示需要的输出(白名单) 最方便的当然是通过管道使用 grep 过滤了,这样可以使用 grep 强大的正则表达式匹配.简单的匹配一行当中的某个字符串,例如 MyApp: adb logcat | grep MyApp        adb logcat |

  • 关于shell命令的定向输出 2>&1

    mycommand >mylog.txt 2>&1 应该是最经典的用法了. 命令的结果可以通过"%>"的形式来定向输出,%表示文件描述符:1为标准输出stdout.2为标准错误stderr.系统默认%值是1,也就是"1>",而1>可以简写为>,也就是默认为>.stdout的默认目标是终端,stderr的默认目标为也是终端.我们在批处理中执行: echo text >result.txt ,我们就可以在屏幕上会看

  • PowerShell中使用Out-String命令把对象转换成字符串输出的例子

    本文介绍在PowerShell中如何将cmdlet输出的对象,转换为string字符串类型,便于后期的处理. PowerShell中的cmdlet输出的结果都是以对象(Object)的形式存在的.对于Object类型,在后期处理时有利有弊,当然利大于弊.但某些时候,我们希望cmdlet输出的结果直接是字符串,那应该怎么来实现呢? PowerShell中提供了一个Out-String的cmdlet,来看看它的介绍:Out-String cmdlet 将 Windows PowerShell 管理的

  • shell学习之printf命令格式化输出语句

    简介 printf 命令用于格式化输出, 是echo命令的增强版.它是C语言printf()库函数的一个有限的变形,并且在语法上有些不同. 注意:printf 由 POSIX 标准所定义,移植性要比 echo 好. 如同 echo 命令,printf 命令也可以输出简单的字符串: $printf "Hello, Shell\n" Hello, Shell $ printf 不像 echo 那样会自动换行,必须显式添加换行符(\n). printf 命令的语法: printf  form

  • shell 脚本中获取命令的输出的实现示例

    这个主要介绍的方法是获取命令的输出内容,而不是命令执行成功与否的返回值. 通常情况下,在shell脚本中需要获取命令的输出内容,然后根据输出内容判断下一步的执行操作. 比较常用的一种方式就是, 匹配命令输出的内容中是否存在某些关键字,选择执行的不同动作.比较常用的一种方式就是采用反向单引号的方式 --  保存结果的变量名=`需要执行的linux命令` 这种方式在使用时,有些细节的地方需要注意. 先用几个例子来说明一下. 比如在CentOS7环境中,使用rpm -qa命令查询某些rpm包是否安装,

  • Linux Shell脚本中获取本机ip地址方法

    方法一:ifconfig -a ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:" 命令解析 ifconfig -a  和window下执行此命令一样道理,返回本机所有ip信息 grep inet                  截取包含ip的行 grep -v 127.0.0.1      去掉本地指向的那行 grep -v inet6             去掉

  • Shell脚本中获取进程ID的方法

    提问: 我想要知道运行中脚本子shell的进程id.我该如何在shell脚本中得到PID. 当我在执行shell脚本时,它会启动一个叫子shell的进程.作为主shell的子进程,子shell将shell脚本中的命令作为批处理运行(因此称为"批处理进程"). 在某些情况下,你也许想要知道运行中的子shell的PID.这个PID信息可以在不同的情况下使用.比如,你可以使用shell脚本的PID在/tmp下创建一个唯一的临时文件.有时侯脚本需要检测所有运行的进程,它可以从进程列表中排除自身

  • 基于shell脚本中cd命令无效的解决方法

    在学习的时候,经常要切换到固定的文件夹,于是写了个shell脚本用cd命令切换却发现目录切换不了. 代码如下: #! /bin/bash # c.sh cd /mnt/hgfs/vmshare pwd 解释:执行的时候是./c.sh来执行的,这样执行的话终端会产生一个子shell(类似于C语言调用函数),子shell去执行我的脚本,在子shell中已经切换了目录了,但是子shell一旦执行完,马上退出,子shell中的变量和操作全部都收回.回到终端根本就看不到这个过程的变化. 验证解释: #!

  • 在shell脚本中获取上个月最后一天的日期方法

    linux中用date命令来获取上个月最后一天的日期: $ date -d"`date +%Y%m01` last day" +%Y%m%d 20161231 编写脚本getdate.sh: #! /bin/sh nowdate=`date +%Y%m01` #本月第一天 startdate=`date -d"$nowdate last month" +%Y%m%d` #上个月第一天 enddate=`date -d"$nowdate last day&q

  • Shell脚本中多命令逻辑执行顺序的方法详解

    Linux中可以使用分号";".双and号"&&"和双竖线"||"来连接多个命令.单"&"符号也算命令连接符号,只不过它是将其前面的命令放入后台执行,所以可以变相地实现命令并行执行. 1.分号";" command1 ; command2 命令之间没有逻辑关系.分号连接的命令会按照顺序从前向后依次执行,但分号两端的命令之间没有任何逻辑关系,所有写出来的命令最终都会被执行,即使分号前面

  • Shell脚本中获取本机ip地址的3个方法

    方法一: 复制代码 代码如下: /sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:" or /sbin/ifconfig|sed -n '/inet addr/s/^[^:]*:\([0-9.]\{7,15\}\) .*/\1/p' 方法二: 复制代码 代码如下: local_host="`hostname --fqdn`" local_i

  • Shell脚本中执行sql语句操作mysql的5种方法

    对于自动化运维,诸如备份恢复之类的,DBA经常需要将SQL语句封装到shell脚本.本文描述了在Linux环境下mysql数据库中,shell脚本下调用sql语句的几种方法,供大家参考.对于脚本输出的结果美化,需要进一步完善和调整.以下为具体的示例及其方法. 1.将SQL语句直接嵌入到shell脚本文件中 复制代码 代码如下: --演示环境  [root@SZDB ~]# more /etc/issue  CentOS release 5.9 (Final)  Kernel \r on an \

  • Java远程调用Shell脚本并获取输出信息【推荐】

    1.添加依赖 <dependency> <groupId>ch.ethz.ganymed</groupId> <artifactId>ganymed-ssh2</artifactId> <version>262</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId&g

  • 如何利用 tee 命令调试shell脚本中的管道

    目录 实例 执行脚本 问题 原因 验证 总结 实例 下面是一个简单的脚本,脚本中 processid 函数的作用是查询指定进程名字的进程ID,在管理linux服务器的过程中,这个是很常见的功能,processid 函数作用是利用多层管道命令查询进程ID,以下是测试脚本源码 #!/bin/sh processid() { ipid=$(ps -ef | grep -w $1 | grep -v grep | awk '{print $2}') echo $ipid } case "$1"

随机推荐