Каков безопасный способ получить статус возврата от выполненной команды оболочки в C ++? - PullRequest
0 голосов
/ 05 сентября 2018

Поскольку функция std::system(const char* command) из cstdlib не гарантирует, что вернет правильный статус возврата из оболочки , то как я могу запустить команду в оболочке с помощью c / c ++ и получить гарантия, что даст мне правильное возвращаемое значение?

В моем случае, например, я выполнил команду с:

bool is_process_running(std::string p_name){
  std::string command_str= "ps aux | grep '" + p_name + "' | egrep -v '(grep|bash)'";

  int result(0);
  result= system(command_str.c_str());

  return result == 0;
}

Если я, например, запускаю ps aux | grep 'my_process' | egrep -v '(grep|bash)' непосредственно в терминал и после этого echo $?, я вижу, что он возвращает 0, потому что my_process работает и также возвращает 1, когда я использую не запущенный процесс , Но приведенный выше код возвращает другое значение. Этот код работал, когда я тестировал в CentOs 6, но сейчас в CentOs 7 больше не работает. Итак, что я могу использовать для запуска команды оболочки и получения правильного результата?

Я также нашел решение с помощью команды pidof, но не могу использовать это, потому что pidof не учитывает параметры, переданные в my_process, которые мне нужны, так как у меня много экземпляров этого процесса, каждый из которых имеет разные аргументы.

1 Ответ

0 голосов
/ 05 сентября 2018

Проблема в том, что статус выхода Bash не обязательно является статусом выхода последней выполненной команды. Если в команде, которую вы передаете, есть ошибка, вы не сможете отличить ее от egrep, если ничего не найдено.

Что вам нужно сделать, так это получить статус выхода и проанализировать выход (как для стандартного вывода, так и для стандартной ошибки). Этого можно достичь, скопировав большую часть функций system: сначала создайте канал для вывода (и stderr, и stdout могут использовать один и тот же канал), затем раскройте новый процесс для запуска оболочки, а затем выполните оболочку и конвейер .

В родительском процессе вы ждете, пока ребенок выйдет из , и получите статус выхода. Если он равен нулю, то вы знаете, что все работало нормально, и вы можете отбросить все выходные данные из канала. Если он ненулевой, вы должны прочитать выходные данные из канала, чтобы увидеть, что произошло, если произошла какая-то ошибка, кроме egrep fail.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...