当我在命令行上运行以下命令时#!/bin/bash
出现错误zsh: event not found: /bin/bash
。
我在 Mac Ventura 上。
如果我运行zsh
该命令,它工作正常,那么问题就出在/bin/bash
。
有人知道发生了什么事吗?
答案1
解释
#!/bin/bash
是常见的 shebang。要成为 shebang,此行必须是脚本的第一行。
当您将脚本作为可执行文件启动时,脚本中的 shebang 对内核很重要。shebang 会告诉内核要启动哪个解释器。脚本的路径会传递给解释器。
解释器本身(/bin/bash
在本例中)应该忽略 shebang。在许多解释器(包括bash
)中,这不需要特殊处理,因为在许多语言中,#
无论如何都会开始注释;从解释器的角度来看,shebang 只是一个注释。
如果脚本中的 shebang 是#!/bin/zsh
,并且您直接将脚本作为可执行文件运行(例如/path/to/the-script
或./the-script
),或者如果您明确调用zsh
以解释带有任何 shebang 的脚本(例如zsh ./the-script
),则将zsh
以非交互方式运行,并将 shebang 解释为注释。这很好;当解释器到达 shebang 时,shebang 已经完成了其使命,可以(或者更确切地说:应该)安全地被忽略。
看起来你粘贴#!/bin/bash
到了交互的 zsh
。默认情况下,交互zsh
不会#comments
像其他 shell 那样将其视为注释,您需要运行setopt interactive_comments
才能启用该功能。您zsh
尝试将其解释#!/bin/bash
为命令。然后由于 而启动了历史记录扩展!
。这就是您得到 的原因zsh: event not found: /bin/bash
。
setopt interactive_comments
在这种情况下不是解决方案。如果您要粘贴的代码以 开头#!/bin/bash
,则明确表明该代码适用于bash
,而不是zsh
。您不应盲目地将其提供给任何zsh
,无论是否交互。
解决方案
将以 开头的整个代码片段保存到#!/bin/bash
常规文件中,使文件可执行(使用chmod +x
)并执行它。shebang 的机制将完成其工作,并将bash
开始解释 的代码bash
。这是运行此类代码片段的正确方法。
更广阔的视野
一般来说,如果你想通过将代码片段粘贴到交互式解释器来运行它,那么你需要自己完成内核的 shebang 相关工作:你需要关注 shebang 并选择正确的解释器。在你的情况下,你可以将代码片段粘贴到交互式 bash 中,它会大概工作。
“可能”,而不是“肯定”,因为相同类型的交互式和非交互式 shell 无论如何都有些不同。例如,如果 shebang 是#!/bin/zsh
,则正确的解释器将是,但由于已禁用zsh
,代码在粘贴到交互式 shell 后无法顺利运行。在这种情况下可能会有所帮助。还有更多差异可能导致交互式 shell 执行代码作者不打算执行的操作。zsh
interactive_comments
setopt interactive_comments
一般来说,运行以 shebang 开头的代码的正确方法是将其保存在常规文件中,使该文件可执行并调用它。在某些情况下如果您根据 shebang 选择解释器(或至少与 shebang 中指定的解释器兼容),则可以粘贴到交互式解释器中。但即使 shell 是正确的,将多行代码片段粘贴到交互式 shell 本身也可能有问题(请参阅这个问题),这就是为什么称为“括号粘贴”的功能对于交互式 shell 很有用。
观察,个人观点
在 Super User 上发布的简短的 shell 代码片段在粘贴到正确的 shell 中时通常是安全的。这样的代码片段可能只包含一个 shebang 来指示正确的 shell。如果我的代码肯定不应该以交互方式粘贴,我倾向于在我的答案中明确警告。不过,如果代码片段包含 shebang,那么通常最好创建一个脚本(文件)而不是以交互方式粘贴。
至少一次 (这里)我使用了一条类似于 shebang 的线,但不能像 shebang 那样工作。它只是为了指示正确的 shell。