背景
在使用QT进行Linux下应用程序开发时,在特定业务需求下,需要在程序中执行Linux的Shell命令。QT中执行Linux命令可以通过QProcess类和system来实现,如果需要得到Shell命令的执行的结果则只能通过QProcess类来实现。本示例解决的一个业务需求是带双网卡的Linux工控机中需要通过增加路由访问其他网段的服务器,最开始是把添加动态路由的功能写在启动脚本(shell脚本)中了,但在测试的时候拔掉对应的网线后,动态添加的路由会丢失,这时再插上网线还是不能与其他网段的服务器进行通讯。
关键代码
/**
* @brief execShellCommand 执行Linux Shell 命令
* @param cmd 要执行的命令
* @param args 参数列表
* @return 返回执行的结果
*/
QString Widget::execShellCommand(QString cmd, QStringList args)
{
QProcess proc;
proc.start(cmd, args, QIODevice::ReadWrite);
proc.waitForFinished();
QString result = proc.readAllStandardOutput();
return result;
}
/**
* @brief routeExists 判断系统路由表中是否存在对应的路由信息
* @param fromNetPart 源网段,比如:10.10.80.0
* @param toGateway 目标网关,比如:192.168.0.1
* @param netmask 子网掩码,比如:255.255.255.0
* @return
*/
bool Widget::routeExists(QString fromNetPart, QString toGateway, QString netmask)
{
bool flag = false; //是否存在对应的路由
QString cmd = "route";
QStringList args = QString("-n").split(" ");
QString routeTable = execShellCommand(cmd, args);
QStringList routeList = routeTable.split("\n");
for(QString routeItem : routeList)
{
// qDebug() << routeItem;
if (routeItem.contains(fromNetPart) && routeItem.contains(toGateway) && routeItem.contains(netmask))
{
flag = true;
break;
}
}
return flag;
}
void Widget::on_pushButton_2_clicked()
{
QString fromNetPart = "10.10.80.0"; //表示当前网段
QString toGateway = "192.168.0.1"; //目标网关
QString netmask = "255.255.255.0"; //子网掩码
if (ui->txtFromNetPart->text() != "")
{
fromNetPart = ui->txtFromNetPart->text();
}
if (ui->txtNetmask->text() != "")
{
netmask = ui->txtNetmask->text();
}
if (ui->txtToGateway->text() != "")
{
toGateway = ui->txtToGateway->text();
}
qDebug() << "execute Route command ... begin";
qDebug() << "---------------------------------------";
bool flag = routeExists(fromNetPart, toGateway, netmask);
if (!flag)
{
// 定义添加路由的命令
QString strCommand = QString("route add -net %1 netmask %2 gw %3").arg(fromNetPart, netmask, toGateway);
qDebug() << strCommand;
system(strCommand.toStdString().data());
}
qDebug() << "---------------------------------------";
qDebug() << "execute Route command ... end";
}