Портативный способ выяснить, существует ли команда (C / C ++) - PullRequest
8 голосов
/ 21 мая 2009
Стандартная библиотека

C предоставляет функции system и popen для запуска команды. Но есть ли портативный способ определить, существует ли команда?

Ответы [ 4 ]

11 голосов
/ 21 октября 2016

Для систем POSIX я обнаружил, что это работает очень хорошо (в этом примере я проверяю avconv):

if (system("which avconv > /dev/null 2>&1")) {
    // Command doesn't exist...
} else {
    // Command does exist, do something with it...
}

Перенаправление на / dev / null просто для того, чтобы ничего не печаталось на стандартный вывод. Он полагается на значение выхода только из команды which.

5 голосов
/ 21 мая 2009

Нет, для этого не существует стандартной функции C.

Единственное решение Unix - разделить getenv("PATH") на : (двоеточие) и попытаться найти исполняемый файл команды (с функцией stat) в каталогах.

4 голосов
/ 21 мая 2009

Хотя я не думаю, что есть полностью переносимый способ сделать это (некоторые системы даже не поддерживают интерпретаторы команд), * ​​1001 * возвращает 0, если не было ошибок при выполнении вашей команды. Я полагаю, вы могли бы просто попробовать запустить вашу команду, а затем проверить возвращаемое значение системы.

Чтобы проверить, доступен ли интерпретатор команд, позвоните system( NULL ) и проверьте ненулевое значение.

3 голосов
/ 01 апреля 2014

Вот способ сканирования всех путей, хранящихся в переменной PATH, поиск исполняемого файла mathsat:

#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>
#include <iostream>

using namespace std;

int main ()
{
  struct stat sb;
  string delimiter = ":";
  string path = string(getenv("PATH"));
  size_t start_pos = 0, end_pos = 0;

  while ((end_pos = path.find(':', start_pos)) != string::npos)
    {
      string current_path =
        path.substr(start_pos, end_pos - start_pos) + "/mathsat";

      if ((stat(mathsat_path.c_str(), &sb) == 0) && (sb.st_mode & S_IXOTH))
        {
          cout << "Okay" << endl;
          return EXIT_SUCCESS;
         }

      start_pos = end_pos + 1;
     }

  return EXIT_SUCCESS;
}
...