shell脚本之获取其它进程的标准输出
1、通过管道将标准输出重定向到其它进程的标准输入[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-Continuous
一 将当前命令(进程)的标准输出重定向到其它命令(进程)的标准输入
通过管道符“|”将当前命令(进程)标准输出重定向到其它命令(进程)的标准输入
[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)