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

Eva*_*ser 28 bash

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

-bash: {command}: command not found
Run Code Online (Sandbox Code Playgroud)

-开头的那个是什么意思?

Joh*_*024 28

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

来自man bash

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

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

可以自动添加破折号的一种方法是,如果 shell 以exec. 从Bash 手册

exec [-cl] [-a name] [command [arguments]]
Run Code Online (Sandbox Code Playgroud)

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

例子

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

$ exec bash
$ nonexistent
bash: nonexistent: command not found
Run Code Online (Sandbox Code Playgroud)

其次,与:

$ exec -l bash
$ nonexistent
-bash: nonexistent: command not found
Run Code Online (Sandbox Code Playgroud)

  • 我认为您引用的文档部分与您的解释不符。`exec -l` 前面有一个破折号这一事实可能会导致 bash 作为 `-bash` 运行,但这本身并不能说明它是一个登录 shell,而且很有可能OP 根本没有使用 `exec -l`。文档中说`-bash` 使它成为登录shell 的部分是“INVOCATION 登录shell 是一个参数零的第一个字符是-,或者一个以--login 选项开头的shell。” (3认同)

小智 15

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

自古以来,login程序argv[0]在执行用户的 shell 时就在前面加上了一个破折号,而 shell 已经认识到这是一个标志,表明它应该作为一个“登录 shell”。它记录在 V7 手册页中:login(1) , sh(1)

所有提供类似登录服务(验证用户并运行 shell)的程序都应遵循“前置破折号”规则。例如, sshd 就像您在ssh/session.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.
 */
Run Code Online (Sandbox Code Playgroud)

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

  • 尽管现在大多数 shell 都有 `-l` 选项,`login` 仍然不使用它。所有 shell 都应该将 `argv[0]` 的前缀识别为“官方”机制。 (2认同)