which shutdown
回报
/usr/bin/shutdown
我也尝试过sudo which shutdown
以防万一......但得到了相同的结果。
我理解了
lrwxrwxrwx 1 root root 9 Dec 13 03:38 /usr/bin/shutdown -> systemctl
我也可以做类似的事情(2小时内关闭机器)
sudo shutdown -h +120
但如果我尝试像这样的愚蠢的事情:
sudo systemctl -h +120
我收到错误...
当我发出问题时,shutdown
我实际上是在调用吗/usr/bin/shutdown
?如果是这样,从 shutdown 到 systemctl 的链接实际上是如何工作的?
简短回答
程序可以知道它被调用的名称;它通过检查 来了解自己的名字
argv[0]
。这允许相同的可执行文件在不同的名称( example )下表现不同,或者单个可执行文件在通过不同命名的符号链接(example)调用时表现不同。在您的情况下,实际的
systemctl
可执行文件知道它是否被调用为systemctl
或shutdown
或其他。它会相应地调整其行为。额外细节
参数数组由父进程设置。
argv[0]
名称是一种约定(不是严格要求) 。家长可以遵守也可以不遵守约定。当您从 shell 运行时systemctl
,shutdown
shell 是父级,并且遵循约定;一般来说,shell 遵循约定。login
不遵循约定的一个示例是(以及尝试模仿它的工具)的行为:login
在第零个参数中使用前导破折号来通知子 shell 它应该是登录 shell。我们假设登录 shell 是 Bash。尽管可执行文件已命名,但shell 中echo "$0"
会向您显示。这个前导破折号是另一个约定。-bash
bash
您可以
systemctl
使用任意名称运行。有些名称很特殊,它们改变了 的行为systemctl
,这是故意支持像您观察到的那样的符号链接。在我的 Debian 12 中,这些是(除其他外)shutdown
和runlevel
. 您不需要创建符号链接或副本来将任意值传递给argv[0]
,systemctl
您可以使用exec -a
Bash。使用任意的示例
argv[0]
(这些示例假设
systemctl
可以通过 访问$PATH
。如果需要,请提供完整路径名。)事实上,您可以使用符号链接
systemctl
(如您的shutdown
)并仍然传递任意argv[0]
. 例子:修复你的“愚蠢的命令”
你的“愚蠢的命令”
可以这样修复:
shutdown
这里根本没有使用指定的符号链接(它可能不存在),systemctl
直接调用可执行文件;它的行为仍然像shutdown
因为我们将正确的名称 (shutdown
) 传递为argv[0]
。