shell脚本之获取其它进程的标准输出

53 篇文章 9 订阅

一 将当前命令(进程)的标准输出重定向到其它命令(进程)的标准输入

    通过管道符“|”将当前命令(进程)标准输出重定向到其它命令(进程)的标准输入

[zhaominyong@localhost yum.repos.d]$ ll | awk '{print $1,$9}'
total 
-rw-r--r--. CentOS-Linux-AppStream.repo
-rw-r--r--. CentOS-Linux-BaseOS.repo
-rw-r--r--. CentOS-Linux-ContinuousRelease.repo
-rw-r--r--. CentOS-Linux-Debuginfo.repo
-rw-r--r--. CentOS-Linux-Devel.repo
-rw-r--r--. CentOS-Linux-Extras.repo
-rw-r--r--. CentOS-Linux-FastTrack.repo
-rw-r--r--. CentOS-Linux-HighAvailability.repo
-rw-r--r--. CentOS-Linux-Media.repo
-rw-r--r--. CentOS-Linux-Plus.repo
-rw-r--r--. CentOS-Linux-PowerTools.repo
-rw-r--r--. CentOS-Linux-Sources.repo

二 获得其它命令(进程)的标准输出

可以通过反引用符号获取其它指令的标准输出,如:

[zhaominyong@localhost yum.repos.d]$ echo `ll | awk 'BEGIN{OFS="|";ORS=";"}{print $1,$9}'`
total|;-rw-r--r--.|CentOS-Linux-AppStream.repo;-rw-r--r--.|CentOS-Linux-BaseOS.repo;-rw-r--r--.|CentOS-Linux-ContinuousRelease.repo;-rw-r--r--.|CentOS-Linux-Debuginfo.repo;-rw-r--r--.|CentOS-Linux-Devel.repo;-rw-r--r--.|CentOS-Linux-Extras.repo;-rw-r--r--.|CentOS-Linux-FastTrack.repo;-rw-r--r--.|CentOS-Linux-HighAvailability.repo;-rw-r--r--.|CentOS-Linux-Media.repo;-rw-r--r--.|CentOS-Linux-Plus.repo;-rw-r--r--.|CentOS-Linux-PowerTools.repo;-rw-r--r--.|CentOS-Linux-Sources.repo;

三 QProcess实现管道方式

The following shell command:
 command1 | command2

注意:管道是进程间通信的方式, command1 | command2是进程1的标准输出重定向到进程2的标准输入。在QT中通过QProcess process1; process1.start("command1 | command2");是获取不到标准输出的,即process1.readAllStandardOutput()是获取不到信息的。

需要用如下方式两种方式获取

方式一:

Can be accomplished with QProcess with the following code:


 QProcess process1;
 QProcess process2;

 process1.setStandardOutputProcess(&process2);

 process1.start("command1");
 process2.start("command2");

缺陷:有些命令可以用上述方式,如:ll | grep CentOS-Linux。有些命令不可以用上述方式,如:ll | awk 'BEGIN{OFS="|";ORS=";"}{print $1,$9}'。这时可以考虑方式二:获取其它命令(进程)的结果到当前命令(进程)

方式二:

获取其它命令(进程)的结果到当前命令(进程)。如:

     QProcess process;
     process.start("echo `ll | awk 'BEGIN{OFS="|";ORS=";"}{print $1,$9}'`");
     if (!process.waitForStarted())
         return false;
     if (!gzip.waitForFinished())
         return false;

     QByteArray result = process.readAll();

方式三:使用管道函数popen

使用linux系统函数popen(cmd,"r")读的方式获取结果信息。如:

/**
 * @brief popen()函数通过创建一个管道,调用fork()产生一个子进程,执行一个shell以运行命令来开启一个进程。
 * @param cmd,是一个指向以 NULL 结束的 shell 命令字符串的指针。这行命令将被传到 bin/sh 并使用 -c 标志,shell 将执行这个命令
 * @param result 输出结果
 * @note
 */
void executeCMD(const char* cmd, QString &result)
{
    char buf_ps[1024] = { 0 };
    FILE* ptr = nullptr;
    // 只能是读或者写中的一种,得到的返回值(标准 I/O 流)也具有和 type 相应的只读或只写类型。
    // 如果 type 是 “r” 则文件指针连接到 command 的标准输出;如果 type 是 “w” 则文件指针连接到 command 的标准输入。
    qDebug() << cmd;
    if ((ptr = popen(cmd, "r")) != nullptr) {
        while (fgets(buf_ps, 1024, ptr) != nullptr) {
            result += buf_ps;
            memset(buf_ps, 0, 1024);
        }
        pclose(ptr);
        ptr = nullptr;
    } else {
        qCritical("popen %s error", cmd);
    }
}

方式四

用QProcess运行bash/sh等shell进程,在shell进程中处理命令。如:


    QString cmd("du \"/home/zhaominyong/workspace/testa b\" -sb | tail -1 | awk -F \" \" '{print $1}'");
    QStringList Argv;
    Argv << "-c" << cmd;

    QProcess process;
    process.start("bash", Argv);

    if (!process.waitForStarted())
        return -1;

    if (!process.waitForFinished(-1)) {
        return -1;
    }

    QString ret = process.readAll();

注意:上例子中的cmd参数如果拆分成多个参数加入参数列表Argv时,需要注意字符串"/home/zhaominyong/workspace/testa b"的表示("/home/zhaominyong/workspace/testa b"是du命令的参数,是个目录,且目录有空格,所以需要确保传入du时这个目录路径是用引号扩起来的,不然无法确保目录的完整性)。process.start("bash", Argv)方法内部组装命令行时,参数列表的每一项都会自动用引号扩起来,但是用bash等shell来执行cmd脚本时参数列表的参数传入到真正执行的du命令时,引号可能被脱掉。有两种方式可以避免这种情况:

1、将整个要在shell中执行的命令作为一个参数,如上例。

2、有空格的参数,再在外层封装一层引号。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值