Qt下编码调用Linux的Shell脚本命令

引言

Linux下编写Qt程序,常会碰到需要执行Shell脚本命令的时候。因为简单调用的一个脚本命令,可以大大简化功能实现的复杂度。
调用Shell脚本命令,Qt环境下常用两种方式:
1)使用QProcess开启一个进程,把脚本命令作为参数传递进去。
2)使用Linux系统函数。
不推荐使用系统函数,一是复杂度比较高;二是常常会阻塞进程;三是控制和数据交互不方便。所以本文以下内容都是讲述使用QProcess调用脚本命令的方法。

单条指令调用

用QProcess执行单条脚本指令的代码真的非常简洁,但要理解清楚,应至少掌握三点内容:阻塞与非阻塞、进程与线程、QProcess参数传递。
一、阻塞与非阻塞
但凡熟悉QProcess类的读者应该清楚,QProcess调用外部进程分为阻塞和非阻塞两类方式。

1)QProcess::execute("xxx"); //阻塞方式
2)QProcess process;
   process.start("xxx"); //非阻塞方式

阻塞方式下,新开启的QProcess不执行完毕或中途退出,主进程就会一直等待,卡在那里而不做任何处理。
而在非阻塞方式下,新开启的QProcess不会影响主进程中其它线程的运行。

二、进程与线程
进程比较好理解,一个应用程序就是一个进程,对应控制面板显示的内容。
一个进程可以开启多个线程,通常在一个单独开启的线程中调用QProcess来开启一个新的进程,这样可以最大程度的使新开启的进程不影响主进程中的其它线程(包括主线程)。

三、QProcess参数传递
这里主要还是QProcess的用法。大致分为三步:1)生成一个进程;2)设置环境变量、运行参数;3)启动进程,等待执行。

一个调用QProcess执行压缩文件的例子如下:

bool SysResource::compressDir(const QString srcPath, const QString workPath, const QString zipfile)
{
	QProcess process; //生成进程
	//设置环境变量、运行参数
	process.setWorkingDirectory(workPath);
	QStringList args;
	args << "-mr" << zipfile << srcPath;
	//启动进程,等待执行
	process.start("zip", args);
	if (!process.waitForFinished())
	{
		process.close();
		return false;
	}
	process.close();
	return true;
}

为了不阻塞当前调用的线程,需要把这个函数放在一个线程中。Qt下把函数放在线程的方法如下:

QtConcurrent::run(this, &SysResource::Fuctionname);

多条指令的调用

多条指令调用有两种方法,一是用一个循环,等前一条指令执行完,发出finished()信号后执行下一条;二是把多条指令写在一个Shell Script中,调用这个脚本即可。这里强烈推荐使用第二种方法,因为QProcess无法识别Linux的管道命令等多种命令,而第二种方法完美规避这个问题。可以在QProcess启动后,使用qDebug()显示QProcess.arguments()和QProcess.errorString()来判断指令是否被QProcess识别正确。
1)循环执行指令代码demo如下:

//构造函数中
QProcess *process = new QProcess;
connect(process, SIGNAL(finished(int)), this, SLOT(doNextCommand()));

//槽函数
void SysResource::doNextCommand()
{
	ipRank++;
	if (ipRank < 4)  //定义了Command[4]数组存放了4条指令
	{
		process->start(Command[ipRank]);
	}
	else
	{
		process->close();
	}
}

2)调用外部脚本代码和单条指令类似,如下:

QProcess process;
QStringList args;
args << "/home/LM/xxx.sh";
process.start("sh", args);
if (!process.waitForFinished())
{
	process.close();
	return;
}
process.close();

总结

文中几种方法都是从编写的工程文件中节选而来,在发行版和ARM版的Linux系统中都得到了验证。欢迎和我交流讨论~

发布了47 篇原创文章 · 获赞 45 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/lusanshui/article/details/88720494