基于Qt写的shell命令执行器,基于popen命令执行shell命令,通过pclose获取命令执行状态。
1class ShellCommand
2{
3public:
4 static bool execute(const QString &cmd, const QStringList &arguments = QStringList());
5
6 static QString readOutput(const QString &cmd, const QStringList &arguments = QStringList());
7
8 static QStringList readOutputLines(const QString &cmd, const QStringList &arguments = QStringList());
9};
1. execute接口
-
execute主要是执行能令,返回值为true执行正确,false执行失败。
1ShellCommand::execute(command);
-
这里需要注意的是cmd与arguments最终会合并为一条语句;
-
调用popen后会执行输入的命令;
-
popen的"r"参数为重定向输出,对应的是"w"重定向输入;
-
fp为空则是直接的执行失败;
-
pclose调用后获取进程状态;
-
这里使用WEXITSTATUS(status)为141判断为正确退出。
1bool ShellCommand::execute(const QString &cmd, const QStringList &arguments)
2{
3 QString newCmd;
4 newCmd.append(cmd);
5 if (! arguments.isEmpty())
6 newCmd.append(" " + arguments.join(" "));
7
8 FILE *fp = popen(qPrintable(newCmd), "r");
9 if (fp == NULL)
10 return false;
11
12 int status = pclose(fp);
13 if (status == -1)
14 return false;
15
16 if (! WIFEXITED(status)) {
17 return false;
18 }
19
20 // 141 == SIGPIPE
21 if (WEXITSTATUS(status) != 141) {
22 return false;
23 }
24
25 return true;
26}
2. readOutput接口
-
readOutput主要是执行命令返回结果,这里需要注意的是,当命令执行失败,返回为空字符串。
1ShellCommand::readOutput(command);
-
使用QFile的readAll读取执行命令的输出;
-
这里需要注意的是命令执行错误并不会获取到,而是返回为空;
-
需要获取命令的错误输出,使用errno获取。
1QString ShellCommand::readOutput(const QString &cmd, const QStringList &arguments)
2{
3 QString newCmd;
4 newCmd.append(cmd);
5 if (! arguments.isEmpty())
6 newCmd.append(" " + arguments.join(" "));
7
8 FILE *fp = popen(qPrintable(newCmd), "r");
9 if (fp == NULL)
10 return "";
11
12 QFile file;
13 if (! file.open(fp, QIODevice::ReadOnly)) {
14 pclose(fp);
15 return "";
16 }
17
18 QString result = QString(file.readAll()).trimmed();
19
20 pclose(fp);
21
22 return result;
23}
3. readOutputLines接口
-
readOutputLines主要是执行命令返回结果,以"\n"自动分割成每一个QString。
1ShellCommand::readOutputLines(command);
1QStringList ShellCommand::readOutputLines(const QString &cmd, const QStringList &arguments)
2{
3 return readOutput(cmd, arguments).split("\n");
4}