LINUX.ORG.RU

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

 , , , ,


0

1

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

Пишу программу в 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.

Для начала не нужно создавать QProcess в куче. Ну и ждём через waitForFinished.

Скрипты лучше в .sh файл класть и уже его запускать.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

waiteForFinished не хочу, так как придётся выделять потоки, потом их закрывать, асинхронный режим сам об этом позаботится.Я не против их использования. Просто лишние сложности ведут к ошибкам. Зачем это надо, когда можно проще что-то сделать?

А, вот, насчёт хранения скриптов в отдельных файлах, то в крайнем случае придётся таким образом реализовать функционал, но для меня первоочередной задачей является корректное завершение процесса по kill, если я вызову bash скрипт из файла, то nmap при убиении родителя всё равно будет висеть?

ivantiran
() автор топика

поскольку я посчитал в свое время вызов скрипта слишком костыльным, я писал мини парсер /proc/*/stat на тему поиска ppid и совпадения его с родительским и дальнейшим убиением дитяток

arcanis ★★★★
()
kill -- -"19556"

где 19556 - это QProcess::processId()

x905 ★★★★★
()
Последнее исправление: x905 (всего исправлений: 1)

Маны бы хоть прочел.

OUTPUT:
  -oN/-oX/-oS/-oG <file>: Output scan in normal, XML, s|<rIpt kIddi3,
     and Grepable format, respectively, to the given filename.
  -oA <basename>: Output in the three major formats at once
  -v: Increase verbosity level (use -vv or more for greater effect)
  -d: Increase debugging level (use -dd or more for greater effect)
  --reason: Display the reason a port is in a particular state
  --open: Only show open (or possibly open) ports
  --packet-trace: Show all packets sent and received
  --iflist: Print host interfaces and routes (for debugging)
  --log-errors: Log errors/warnings to the normal-format output file
  --append-output: Append to rather than clobber specified output files
  --resume <filename>: Resume an aborted scan

Баш из c++… Мда.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.