Linux 中是否有任何不进行系统调用的命令?

Linux 中是否有任何不进行系统调用的命令?

我读过有关系统调用的文章,我怀疑是否有任何命令在不进行任何系统调用的情况下运行。如果没有,那么系统调用次数最少的命令是什么?我使用了strace一些命令,但它给出了一个很长的列表。有人能告诉我这样的命令吗?

答案1

/bin/true并且/bin/false应该是系统调用最少的预装命令。

您可以通过静态链接节省一些系统调用:

将以下内容保存为例如minimal.c

int main() {
    return 0;
}

并使用编译

gcc --static -o minimal minimal.c

minimal这将使您获得当前工作文件夹中的程序。

答案2

说到为了“运行”(因此“运行”的含义比您可能指的含义更广泛)程序实际执行了哪些系统调用,不是:首先,系统execve()调用总是为了运行命令(在这种情况下,我认为我们最好谈论可执行文件)本身而执行,并且exit()系统调用总是在main()返回时执行:

C 编译器在 main() 返回后调用 exit()

来源

为了以某种方式解决您的问题,该问题依赖于可执行文件,因此非常广泛:作为概念证明,表明任何实际有用的可执行文件都将使用至少一个系统调用,值得说明的是,首先,如果出现错误,很可能从程序本身执行系统调用;更不用说任何打开/关闭文件描述符的可执行文件都会使用/系统exit()调用。open()close()

最后,任何实际有用的命令很可能至少有一个系统调用(例如,exit()如果程序在执行过程中遇到错误和/或open()如果close()命令必须读取文件)。

答案3

是的。有一些命令无需进行任何系统调用即可运行。

此类命令的一个先决条件是它们内置于 shell 中(bash对于我的系统,是 )。这既消除了设置开销(链接器和 libc 执行的大量系统调用,用于设置代码运行的环境)也消除了最终的 exit() 调用。

strace但这无法帮助您识别这些命令,因为它们不是实际的程序。没有与内置命令相对应的文件,因此如果strace 找到命令,它将是一个外部版本,包含任何过程所需的设置和拆卸。

bash命令help列出了所有可用的内部命令。请注意,其中许多命令也会进行系统调用。有些命令使用系统调用:

  • function
  • for
  • declare
  • true(内置版本;不是/bin/true
  • false(内置版本;不是/bin/false
  • shift
  • set
  • case
  • alias/unalias
  • set/unset

一般来说...如果一个命令是 shell 内部的,不读取输入,不写入输出,并且只使用内存中的变量,那么它可能不使用系统调用。

答案4

如果不进行任何系统调用,程序就无法完成很多有意义的工作。系统调用是程序与程序本身之外的任何事物进行通信的主要方法。

通过内存映射文件或共享内存进行通信是可行的,但首先仍需要系统调用进行设置。之后,无需进一步的系统调用即可进行通信。

程序可以通过信号从外部接收信息。但是,如果没有安装信号处理程序,信号只会终止程序,而安装信号处理程序首先需要系统调用。原则上,程序在处理接收信号结束时也需要进行系统调用,但如果信号设置为在接收时不阻止信号,那么无需系统调用即可离开信号处理程序。这更多的是一种好奇心,而不是一种具有实际应用的有意义的技术。

不进行任何系统调用的程序将消耗其所能获得的所有 CPU 时间,因为睡眠(在大多数情况下)需要系统调用。程序可以处于睡眠状态,因为它正在等待从磁盘加载映射页面。但如果没有系统调用,唯一要加载的映射页面将是可执行文件本身,它很快就会被缓存。

在运行程序时,可以通过修改自己的命令行或环境变量使部分结果对其他程序可见。这些都可以在不进行系统调用的情况下进行修改。

即使程序正常终止也需要系统调用。但程序可以触发信号终止,而无需系统调用。可能触发的信号包括 SIGILL、SIGBUS、SIGFPE、SIGSEGV。

考虑到所有这些,可以编写一个程序,该程序在启动时会对命令行提供的值进行一些计算,并最终根据计算结果通过不同的信号终止。这不是指示计算结果的最有用方法,但肯定是可行的。

相关内容