Корректный выход при выполнении недопустимой команды c

#c #exception #boost #command-line

#c #исключение #повышение #командная строка

Вопрос:

Я использую boost для выполнения команд командной строки из моего приложения. Я использую следующий фрагмент кода, который я инкапсулировал во вспомогательную функцию:

 tuple<string, int> Utility::RunCommand(const stringamp; arguments) const
{
    string response;
    int exitCode;
    try
    {
        ipstream iStream;
        auto childProcess = child(arguments, std_out > iStream);
        string line;

        while (getline(iStream, line) amp;amp; !line.empty())
        {
            response  = line;
        }

        childProcess.wait();
        exitCode = childProcess.exit_code();
    }
    catch (...)
    {
        // log error
        throw;
    }

    return make_tuple(response, exitCode);
}
  

Теперь у меня есть команда, которая выполняется только на машинах с определенными свойствами. Этот метод возвращает ожидаемый ответ и код ошибки на этих машинах. На других машинах он выдает исключение.

Я попытался запустить команду вручную на компьютере, где она должна завершиться с ошибкой, и она возвращает следующий вывод:

 POWERSHELL
PS C:Usersxyz> dummy-cmd
dummy-cmd : The term 'dummy-cmd' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
  dummy-cmd
  ~~~~~~~~~~
      CategoryInfo          : ObjectNotFound: (dummy-cmd:String) [], CommandNotFoundException
      FullyQualifiedErrorId : CommandNotFoundException

COMMAND PROMPT
C:Usersxyz>dummy-cmd
'dummy-cmd' is not recognized as an internal or external command,
operable program or batch file.
  

Как я могу заставить его работать так, чтобы он возвращал ненулевой код ошибки, а не создавал исключение?

Комментарии:

1. Проблема в том, что ваш исполняемый файл не существует. Это то, на что жалуется Powershell.

2. Вы компилируете свой код, чтобы получить a dummy-cmd.exe ?

3. @doron Верно, я знаю об этой части. Мне интересно, есть ли способ вызвать команду, чтобы она возвращала код ошибки вместо исключения?

4. @FredLarson Нет. dummy-cmd.exe существует на одних машинах и отсутствует на других.

Ответ №1:

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

 tuple<string, int> Utility::RunCommand(const stringamp; arguments) const
{
    string response;
    int exitCode;
    try
    {
        ipstream iStream;
        auto childProcess = child(arguments, std_out > iStream);
        string line;

        while (getline(iStream, line) amp;amp; !line.empty())
        {
            response  = line;
        }

        childProcess.wait();
        exitCode = childProcess.exit_code();
    }
    catch (PlatformNotSupportedExceptionamp; e)
    {
        std::cerr << "That operation is not supported on this platform." << std::endl;
        exit(1);
    }
    catch (...)
    {
        std::cerr << "Unspecified error occurred." << std::endl;
        exit(1); // give nonzero exit code
        //throw; // take out this
    }

    return make_tuple(response, exitCode);
}
  

Комментарии:

1. Я могу это сделать. Но есть ли способ избежать попадания в catch? В основном способ выполнения команды таким образом, чтобы она возвращалась из метода. Кроме того, exit(1) выходит из приложения? Я хотел бы вернуться к вызывающей стороне.

2. @commandocaddy Итак, подождите, вы хотите, чтобы исключение было выдано и перехвачено этим методом, который затем возвращается? Или вы вообще не хотите никаких исключений?

3. В идеале никаких исключений вообще. Потому что на огромном количестве машин не будет этого исполняемого файла. Я бы хотел предотвратить обработку исключений, поскольку это может быть дорого.

4. @commandocaddy Тогда почему бы не изменить свой метод, чтобы не генерировать исключение, а вместо этого просто выдать соответствующий код выхода? Тогда вам не понадобится обработка исключений.