LINUX.ORG.RU

Сообщения ivantiran

 

Не могу запустить bash-скрипт в QProcess

Доброго времени суток.

Пишу программу в Qt.

Мне требуется сканировать сегменты сети на наличие активных устройств.

Использую для этого nmap. Дабы не парсить вывод nmap в самом Qt, использую дополнительно фильтры grep и awk.

Собственно, список активных машин в сегменте

proc = new QProcess();
    _proc->setProgram("/bin/bash");
    _proc->setArguments(QStringList() << "-c" << "nmap -sP " + _address + ".0/24 | grep -E -o \"[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$\" | awk -F \".\" '{ if(($4 > 0) && ($4 < 255)) print $0;}'");

Ну, это как бы для примера.

Сканировать придётся много и по таймеру. Может, неочень правильное решение, так как каждый nmap жрёт какое-то количество памяти, нужно выделить достаточно на виртуалке. Но, неважно, пока ничего мудрее не придумал.

Сканировать так же нужно будет и порты, так, что использование чисто дефолтного ping не имеет смысла.

Собственно, в чём проблема. Когда создаю процесс в QProcess, то родительским процессом становится /bin/bash, а при его убиении nmap, awk, grep висят в процессах пока nmap не завершит сканирование. А если я закрыл программу, какой смысл висеть десятку nmap?

Долго лазил по инету и ничего мудрее не придумал, как написать ещё один скрипт для убиения родителя и его потомков.

Собственно, сам виновник данной темы:

#!/bin/bash

PID=$1

METKA=(`ps -A | grep -v PID | awk 'BEGIN{C="NO";}{if($1=='$PID') C="YES";}END{print C;}'`)

if [[ "$METKA" == "YES" ]]
then

for z in `ps -ejH | grep -E "(bash)|(nmap)|(grep)|(awk)" | awk 'BEGIN{N=1;}{PID[N]=$1;name[N]=$6;N++;}END{for(i=1;i<N;i++) {if((PID[i]=='$PID') && ((i+3)<N)) {if((name[i]=="bash")&&(name[i+1]=="nmap")&&(name[i+2]=="grep")&&(name[i+3]=="awk")){print PID[i],PID[i+1],PID[i+2],PID[i+3]; break;}  }}  }'`
do

echo "${z}"

kill ${z}

done

fi

Я не скриптолог, но что получилось, то получилось.

Если я вызываю этот скрипт из терминала, то он штатно выполняет свою работу.

А вот, Qt ругается по-страшному или молчит, но убивать nmapы не собирается. При таком запуске скрипта в деструкторе

QProcess::startDetached("/bin/bash",QStringList() << "-c" << "./script.sh" << QString::number(PID));

выдаёт:

QProcess: Destroyed while process ("/bin/bash") is still running.
QProcess: Destroyed while process ("/bin/bash") is still running.
awk: awk: PID= "192.168.55" 11067
cmd. line:1: BEGIN{C="NO";}{if($1==) C="YES";}END{print C;}
awk: cmd. line:1: ^ syntax error
cmd. line:1: BEGIN{C="NO";}{if($1==) C="YES";}END{print C;}
awk: cmd. line:1: ^ syntax error
QProcess: Destroyed while process ("/bin/bash") is still running.
awk: cmd. line:1: BEGIN{C="NO";}{if($1==) C="YES";}END{print C;}
awk: cmd. line:1: ^ syntax error
QProcess: Destroyed while process ("/bin/bash") is still running.
awk: cmd. line:1: BEGIN{C="NO";}{if($1==) C="YES";}END{print C;}
awk: cmd. line:1: ^ syntax error
grep: ошибка записи: Обрыв канала
grep: ошибка записи: Обрыв канала
grep: ошибка записи: Обрыв канала
grep: ошибка записи: Обрыв канала

При таком:

QProcess::startDetached("/bin/bash",QStringList() << "-c" << "./script.sh " + QString::number(PID));
QProcess: Destroyed while process ("/bin/bash") is still running.
QProcess: Destroyed while process ("/bin/bash") is still running.
QProcess: Destroyed while process ("/bin/bash") is still running.
QProcess: Destroyed while process ("/bin/bash") is still running.

Собственно, на это «is still running» можно не обращать внимания, так как я перед закрытием программы временно закомментил закрытие процесса.

Суть в том, что скрипт из терминала работает:

pavel@astra1:~/newnetmonitor/build-newNetMonitor-Desktop_Qt_5_10_0_GCC_64bit-Debug$ ./script.sh 11704
11704
11705
11706
./script.sh: строка 15: kill: (11706) - Нет такого процесса
11707
./script.sh: строка 15: kill: (11707) - Нет такого процесса

а из Qt нет. Awk и grep по идее можно не удялять, так как они сами закрываются при убиении nmap, что и видно в сообщении.

В чём может быть причина и как грамотнее вызывать скрипт так:

QProcess::startDetached("/bin/bash",QStringList() << "-c" << "./script.sh" << QString::number(PID));

или так:

QProcess::startDetached("/bin/bash",QStringList() << "-c" << "./script.sh " + QString::number(PID));

Может я неправильно внешние аргументы в awk подаю «if($1=='$PID')». Не знаю…

В конечном итоге нужно убить родительский процесс и всех его потомков по PID и хотелось бы этот скрипт одной строкой записать, чтобы можно было не из файла, а из Qt вызвать, как я это делаю с nmap.

 , , , ,

ivantiran
()

RSS подписка на новые темы