当您在 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");