假设正在开发的应用程序需要一些功能,可以通过对命令行程序进行系统调用或利用库来实现。假设效率不是问题,那么简单地对程序进行系统调用而不是使用库是不好的做法吗?这样做有什么缺点?
具体来说,这种情况的一个示例是需要从 Web 服务器下载文件的应用程序,可以使用 cURL 程序或 libcURL 库。
假设正在开发的应用程序需要一些功能,可以通过对命令行程序进行系统调用或利用库来实现。假设效率不是问题,那么简单地对程序进行系统调用而不是使用库是不好的做法吗?这样做有什么缺点?
具体来说,这种情况的一个示例是需要从 Web 服务器下载文件的应用程序,可以使用 cURL 程序或 libcURL 库。
除非您只为一个操作系统编写代码,否则无法知道您的系统调用是否会工作。当有系统更新或操作系统升级时会发生什么?如果有库可以执行相同的功能,则
永远不要使用系统调用。
由于依赖性问题,我更喜欢库,即当您调用它时可执行文件可能不存在,但库会存在(假设在您的平台上启动进程时会处理外部库引用)。换句话说,与系统调用相比,使用库似乎可以保证在更多环境中获得更稳定、更可预测的结果。
有几个因素需要考虑。一个关键是外部程序是否会出现在安装了您的软件的所有系统上的可靠性。如果它可能会丢失,那么最好在程序中执行它。
考虑到这一点,您可能会认为加载到您的程序中的额外代码是令人望而却步的——您不需要为应用程序中这样一个很少使用的部分添加代码膨胀。
system() 函数很方便,但也很危险,尤其是因为它通常会调用 shell。更直接地调用程序可能会更好——在 Unix 上,通过 fork() 和 exec() 系统调用。[注意,系统调用与调用函数非常不同system()
,顺便说一句!] OTOH,您可能需要担心确保程序中所有打开的文件描述符都已关闭 - 特别是如果您的程序是某种代表其他程序运行的守护程序用户;如果您不使用特殊权限,这不是什么大问题,但最好不要让被调用的程序访问您不想要的任何东西。您可能需要查看fcntl()
系统调用和FD_CLOEXEC
标志。
通常,如果您将功能构建到程序中,则更容易控制事物,但这不是一个简单的决定。
安全是一个问题。恶意 cURL 可能会对您的程序造成严重破坏。这取决于这是一个以编码速度为主要关注点的个人程序,还是一个以安全性为主要考虑因素的商业应用程序。
系统调用更难安全地进行。
各种有趣的字符都需要正确编码才能传入参数,编码类型可能因平台甚至命令版本而异。因此,进行包含任何用户数据的系统调用需要大量的完整性检查,并且很容易出错。
是的,如上所述,请记住系统调用(如 fcntl() 和 open())和 system() 调用之间的区别。:)
在 ac 程序原型设计的早期阶段,我经常对 grep 和 sed 等程序进行外部调用,以使用 popen() 来操作文件。它不安全,不安全,而且肯定不便携。但它可以让你快速上手。这对我来说很有价值。它让我专注于程序真正重要的核心,这通常是我最初使用 c 的原因。
在高级语言中,您最好有一个很好的理由。:)
我没有做任何一个,而是使用命令行参数和标准输入在你的应用程序周围建立一个 Unix 并构建一个脚本框架。
其他人提到了优点(可靠性、安全性、安全性、便携性等)——但我会扔掉另一个。表现。通常,调用库函数甚至生成一个新线程要比启动一个全新的进程快很多倍(然后您仍然必须正确检查/验证它的执行并解析它的输出!)