Это хорошая идея для вызова команд оболочки в C?

Там'ы командной оболочки Unix (`udevadm инфо-путь г-н к /dev/ttyUSB2), что я хочу вызвать из программы на C. Наверное, около недели борьбы, я смог повторно реализовать это сам, но я Дон'т хотите, чтобы сделать это.

Это широко признано, хорошая практика для меня, чтобы просто позвонить к popen (на"my_command-то", то "Р", У);`, или что ввести неприемлемые проблемы безопасности и вперед, проблем с совместимостью? Он чувствует себя неправильно для меня, чтобы сделать что-то подобное, но я могу'т положить палец на почему это было бы плохо.

Комментарии к вопросу (14)
Решение

Это's не особенно плохо, но есть некоторые оговорки.

  1. как портативный будет ваше решение? Ваш выбрал бинарные работают везде одинаково, результаты выводятся в том же формате и т. д.? Это выход по-разному в настройках "язык" и т. д.?
  2. сколько дополнительной нагрузки можно к этому добавить на ваш процесс? Разветвление бинарные результаты в намного больше нагрузки и требует больше ресурсов, чем выполнение библиотечные вызовы (вообще говоря). Это приемлемо в вашем случае?
  3. Есть ли вопросы безопасности? Может кому-то подставить свою выбрали бинарный с другой, и совершать неблаговидных поступков в дальнейшем? Используете ли вы пользовательские аргументы для бинарных, и они могли обеспечить ;РМ -РФ / (к примеру) (обратите внимание, что некоторые API позволит вам указать аргументы более надежно, чем просто предоставление им в командной строке)

Я'м, как правило, счастливы выполнение бинарных файлов, когда я'm в известной среде, что я могу предсказать, когда двоичный выход легко разобрать (если необходимо - возможно, Вам просто нужен выход код) и я не'т придется делать это слишком часто.

Как вы'вэ заметил, другой вопрос, сколько труда это повторить, что бинарные делает? Он использует библиотеки также можно использовать?

Комментарии (12)

Она занимает крайнюю осторожность, чтобы защититься от уязвимости инъекции после того, как вы'вэ представил потенциальный вектор. Это's в авангарде ваш ум сейчас, но позже вам может потребоваться возможность выбора ttyUSB0-3, тогда этот список будет использоваться в других местах так оно и будет вынесена следовать один принцип ответственности, то покупатель будет иметь потребность поставить произвольную устройство в списке, и разработчик делает что ** изменение будет иметь ни малейшего представления, что список со временем привыкает небезопасным способом.

Другими словами, код, как если бы большинство нерадивых разработчиков, вы знаете, что делает небезопасным изменения в, казалось бы, несвязанные части Кодекса.

Во-вторых, выход из CLI инструменты не'т, как правило, считаются стабильными интерфейсами, если в документации специально помечает их как таковые. Вы могли бы быть в порядке рассчитывают на них скрипт запуска, которые можно устранить самостоятельно, но не за то, что вы развернуть к клиенту.

В-третьих, если вы хотите простой способ, чтобы извлечь значение из вашего программного обеспечения, то шансы еще кто-то тоже хочет. Искать библиотека, которая уже делает то, что вы хотите libudev уже был установлен на моей системе.:

в

#include 
#include 
#include 

int main(int argc, char* argv[]) {
    struct stat statbuf;

    if (stat("dev/ttyUSB2", &statbuf) < 0)
        return -1;
    struct udev* udev = udev_new();
    struct udev_device *dev = udev_device_new_from_devnum(udev, 'c', statbuf.st_rdev);

    printf("%s\n", udev_device_get_devpath(dev));

    udev_device_unref(dev);
    udev_unref(udev);
    return 0;
}

Есть и другие полезные функции в этой библиотеке. Я думаю, если вам это нужно, некоторые смежные функции может быть слишком удобно.

Комментарии (8)

В вашем конкретном случае, где вы хотите вызвать udevadm, я'd и подозреваю, что вы могли тянуть в `используется как библиотека и сделать соответствующие вызовы функций в качестве альтернативы?

например, вы могли бы взглянуть на то, что сама udevadm делает, когда вызов в "информация" в режиме: https://github.com/gentoo/eudev/blob/master/src/udev/udevadm-info.c и сделать соответствующие вызовы как для тех, udevadm делает.

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

Комментарии (2)

Ваш вопрос, казалось, вызов для ответа на лес, и ответы здесь, кажется, как отвечает на дереве, так что я думал, что я'd и дать вам ответ лес.

Это очень редко, как пишутся программы на C. Это всегда как shell-скрипты пишутся, а иногда как на Python, программы на Perl или Ruby написано.

Люди обычно пишут на C для легкого использования системных библиотек и прямой низкоуровневый доступ к системным вызовам ОС, а также для скорости. И C-это язык трудно писать, так что если человек не'т необходимость этих вещей, то они не'т использовать С. Также программы на C обычно имеют только ЗАВИСИМОСТИ на разделяемые библиотеки и файлы конфигурации.

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

Есть некоторые дополнительные вопросы. Безопасность и переносимость касается людей полностью справедливы. Они одинаково действительны для shell скриптов, конечно, но люди ждут этих видов вопросов в сценариях оболочки. Но программы на C, как правило, не ожидается, этот класс безопасности, что делает его более опасным.

Но, на мой взгляд, самые большие опасения связаны с образом к popen будет взаимодействовать с остальной частью вашей программы. к popen для создания дочернего процесса, читать его вывод и собирать ее статус выхода. В то же время, что процесс' stderr будут подключены к одной стандартной ошибки в вашей программе, которые могут привести к нежелательным выход, и его stdin будет такой же, как вашу программу, что может вызвать другие интересные вопросы. Вы можете решить эту проблему, в том числе в </dev/нуль 2 и GT;/dev/нуль в строке, передаваемой вк popen`, поскольку он'ы интерпретируется оболочкой.

И к popen создает дочерний процесс. Если ты сделаешь что-то с обработкой сигнала или разветвление процессов вы можете в конечном итоге получить лишняя сигнала sigchld сигналы. Ваши призывы к ждать могут взаимодействовать как-то странно с к popen и, возможно, создать странные условия гонки.

Интересы безопасности и переносимости есть конечно. Поскольку они предназначены для shell-скрипты или что-то, что запускает другие исполняемые файлы в системе. И вы должны быть осторожны, что люди, используя вашу программу не'т возможность получить раковиной мета-charcaters в строку вы передаете в к popen, поскольку эта строка дается непосредственно к ш с Ш-с в <string из к popen как один аргумент>.

Но я не думаю, что они поэтому странно видеть программа с помощью к popen`. Причина это странно, потому что обычно на языке низкого уровня, и к popen-это не низкий уровень. И потому применение к popen мест конструктивных ограничений на вашу программу, потому что это будет странно взаимодействовать с вашей программой's стандартный ввод и вывод, и сделать его боль, чтобы сделать свой собственный процесс управления и обработки сигнала. И потому, что программы С, как правило, не ожидается зависимости от внешних исполняемых файлов.

Комментарии (0)

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

С точки зрения вашей программы ее выполнение в нормальную домашнюю обстановку, с точки зрения безопасности, если кто-то нарушает свою программу, то она имеет доступ только к элементам, которые вы предоставили, когда вы сделали копию.

Такая установка называется chroot-окружении для более подробной информации см. chroot-окружении.

Его обычно используют для создания общедоступных серверов и т. д.

Комментарии (1)