Плохо ли использовать функцию system(), когда вместо нее можно использовать библиотечные функции?Почему?

StackOverflow https://stackoverflow.com/questions/509743

  •  21-08-2019
  •  | 
  •  

Вопрос

Допустим, разрабатываемому приложению необходимы некоторые функциональные возможности, которые можно реализовать, выполнив системный вызов программы командной строки или используя библиотеку.Если предположить, что эффективность не является проблемой, является ли плохой практикой просто выполнять системный вызов программы вместо использования библиотеки?Каковы недостатки этого?

Чтобы сделать ситуацию более конкретной, примером этого сценария может служить приложение, которому необходимо загрузить файл с веб-сервера. Для этого можно использовать либо программу cURL, либо библиотеку libcURL.

Это было полезно?

Решение

Если вы не пишете код только для одной ОС, невозможно узнать, будет ли вообще работать ваш системный вызов.Что происходит при обновлении системы или ОС?
Никогда используйте системный вызов, если есть библиотека для выполнения той же функции.

Другие советы

Я предпочитаю библиотеки из-за проблемы с зависимостями, а именно: исполняемый файл может отсутствовать, когда вы его вызываете, но библиотека будет (при условии, что ссылки на внешние библиотеки будут обработаны при запуске процесса на вашей платформе).Другими словами, использование библиотек, по-видимому, гарантирует более стабильный и предсказуемый результат в большем количестве сред, чем системные вызовы.

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

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

Функция system() удобна, но опасна, не в последнюю очередь потому, что обычно она вызывает оболочку.Возможно, вам лучше вызвать программу напрямую - в Unix, через системные вызовы fork() и exec().[Обратите внимание, что системный вызов сильно отличается от вызова system() функция, кстати!] OTOH, вам, возможно, придется побеспокоиться о том, чтобы все дескрипторы открытых файлов в вашей программе были закрыты - особенно если ваша программа представляет собой своего рода демон, работающий от имени других пользователей;это меньшая проблема, если вы не используете специальные привилегии, но все же рекомендуется не предоставлять вызываемой программе доступ ко всему, что вы не планировали.Возможно, вам придется просмотреть fcntl() системный вызов и FD_CLOEXEC флаг.

Как правило, легче контролировать ситуацию, если вы встроите функциональность в свою программу, но это нетривиальное решение.

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

Системные вызовы гораздо сложнее выполнять безопасно.

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

Да, как упоминалось выше, имейте в виду разницу между системными вызовами (например, fcntl() и open()) и вызовами system().:)

На ранних стадиях создания прототипа программы на языке C я часто вызываю внешние вызовы таких программ, как grep и sed, для манипуляций с файлами с помощью popen().Это небезопасно, ненадежно и уж точно не портативно.Но это может позволить вам начать работу быстро.Это ценно для меня.Это позволяет мне сосредоточиться на действительно важном ядре программы, обычно именно на причине, по которой я в первую очередь использовал c.

В языках высокого уровня вам лучше иметь довольно вескую причину.:)

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

Другие упомянули хорошие моменты (надежность, безопасность, безопасность, портативность и т. д.), но я выброшу еще один.Производительность.Как правило, вызвать библиотечную функцию или даже создать новый поток во много раз быстрее, чем запустить целый новый процесс (и тогда вам все равно придется правильно проверять/проверять его выполнение и анализировать его выходные данные!)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top