“找不到命令”错误中“bash”之前的破折号“-”是什么意思?

“找不到命令”错误中“bash”之前的破折号“-”是什么意思?

当您在 bash 提示符下输入无效命令时,您会收到消息

-bash: {command}: command not found

-一开始的意思是什么?

答案1

这意味着它是一个登录 shell。

man bash

登录 shell 的参数零的第一个字符是 -,或者以 --login 选项开头。

(在bash术语中,“第零”参数是命令名称,在您的情况下,是bash。) bash使用它作为执行登录活动的信号,例如执行.bash_profile等。

自动添加破折号的一种方法是 shell 以 启动exec。来自bash手册:

exec [-cl] [-a name] [command [arguments]]

[...] 如果-l提供了该选项,shell 会在传递给的第 0 个参数的开头放置一个破折号命令

例子

比较这两次运行命令的尝试nonexistent。首先没有-l

$ exec bash
$ nonexistent
bash: nonexistent: command not found

其次,:

$ exec -l bash
$ nonexistent
-bash: nonexistent: command not found

答案2

就其本身而言,另一个答案很好,但值得一提的是,该功能比 bash 更通用。

自古以来,login程序在执行用户的 shell 时都会在前面添加一个破折号argv[0],并且 shell 会将其识别为一个标志,表明它应该充当“登录 shell”。它记录在 V7 手册页中:登录(1),嘘(1)

所有提供类似登录服务(验证用户身份并运行 shell)的程序都应遵循“前置破折号”规则。例如,sshd 的作用如您所见ssh/会话.c在此评论下:

/*
 * If we have no command, execute the shell.  In this case, the shell
 * name to be passed in argv[0] is preceded by '-' to indicate that
 * this is a login shell.
 */

所有 shell 都能识别前导破折号。经典的 Bourne shell 或原始 csh 中不存在等效-l选项,但大多数较新的 shell(bash、dash、ksh、yash、tcsh、zsh、rc、es、fish 和 csh 的任何半新版本)都有它。

答案3

该函数的参数main是由父进程手动设置的,而不是由内核预设的。父进程可以将任何值设置为子进程的argv[0].看man 3 exec

例如,家长可以这样做

execlp("bash", "-bash");

相关内容