2017-02-22 12 views
-4

Как определить, успешно ли выполнена команда или существует ли она на C? Это должно быть совместимо с несколькими архитектурами и маршрутизаторами (не спрашивайте haha)Определить, является ли команда успешной/существует c

Я думал об использовании popen или system или exec (v) (l). Но команда, которую я хочу проверить, - sendmail. Поскольку sendmail - это команда, которая работает вечно без вывода, это будет немного сложно сделать. Есть идеи?

Заранее спасибо.

+0

Если вы знаете путь к команде, почему бы просто не выполнить 'stat' и посмотреть, является ли он исполняемым? – codeforester

+0

Дубликат [отправка электронной почты с помощью программы C/C++ в Linux] (http://stackoverflow.com/questions/9317305/sending-an-email-from-acc-program-in-linux) –

+0

CURL - еще одна хорошая способ отправки электронной почты. –

ответ

1

Если вы знаете путь к sendmail, то в соответствии с комментариями используйте stat, чтобы проверить, существует ли он и является исполняемым. Если вы знаете путь поиска, повторите его и проверьте каждый.

Если нет - вы можете передать его /dev/null как stdin, и в этом случае он распечатает сообщение об ошибке и выйдет. Затем вы можете проверить код выхода из процесса - для систем POSIX, код выхода будет 127, если команда не может быть выполнена:

int rc = system("sendmail </dev/null 2>/dev/null"); 
if (WEXITSTATUS(rc)!=127) { 
    /* sendmail was found */ 
} 

Конечно, это требует /dev/null существовать и оболочки перенаправления будут доступны.

Я также перенаправил stderr, иначе вы получите сообщение об ошибке, выводимое из sendmail.

+0

Функция 'system' не вернется, если' sendmail' не выйдет или не завершится. –

+0

@BasileStarynkevitch будет завершен, если вы его подадите из/dev/null. Когда вы начинаете его, как показано выше, он пытается прочитать из stdin – harmic

+0

Thankyou. Это именно то, что мне нужно. – N3Cr0M0rPh

0

Просто попробуйте использовать его. Если он есть, и вы можете его выполнить, это сработает. Если это не так, это не так, и вы можете понять, почему в errno.

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

Во-вторых, он приглашает race condition. Например, предположим, что у вас есть два процесса, работающих над одним и тем же файлом. Время движется вниз.

Process 1        Process 2 
Check if file is readable. 
It's readable! 
             Make the file unreadable. 
Open that file. 
File fails to open. 

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


Избегайте popen и system, где вы можете. Они запускают команду через оболочку, которая предлагает дыры безопасности и непреднамеренные последствия не буквенно-цифровых символов. Вместо этого используйте одну из функций exec[lv]p, которая будет искать PATH для исполняемого файла без вызова оболочки.

Смежные вопросы