【问题标题】:shebang emacs --script runs as bashshebang emacs --script 作为 bash 运行
【发布时间】:2014-02-22 16:41:37
【问题描述】:

我正在尝试将 Emacs Lisp 作为另一种 shell 脚本语言,但遇到了一个奇怪的问题。我在一个名为 hello.el 的文件中编写了以下 Emacs Lisp 脚本,然后使其可执行:

#!/usr/local/bin/emacs --script
(princ "hello world\n")

当我运行它时,我得到了以下信息:

$ ./hello.el
./hello.el: line 2: princ: command not found

经过一些实验,我发现#! 下面的代码是由 Bash 运行的,或者至少是其他一些 shell,而不是 Emacs:

#!/usr/local/bin/emacs --script
foo=bash?
echo $foo
ls -l | sort | tail -1

$ ./hello.el
bash?
total 7984

这对我来说似乎很奇怪,因为在各种 Emacs 文档中有很多对 --script 选项的引用,当我直接使用它运行脚本时它工作正常(即当我将 /usr/local/bin/emacs --script hello.el 粘贴到我的终端时.

真正奇怪的是这个脚本完全按预期工作:

#!/usr/bin/emacs --script
(princ "hello world\n")

但我使用/usr/local/bin/emacs 的原因是它是一个较新的版本; /usr/bin/emacs 的版本是 Apple 提供的随 Mac OS X 一起提供的 Emacs,而 /usr/local/bin/emacs 的版本是通过 brew 安装的,并且更新的版本(Emacs 24 vs 22)。

这里出了什么问题? Emacs 22 和 24 之间有什么变化吗?

【问题讨论】:

    标签: macos bash shell emacs


    【解决方案1】:

    所以我写了这个问题并在意识到问题所在之前先了解了 Mac OS X,并认为我不妨在这里发布答案,因为它有点神秘。希望对您有所帮助。

    问题在于/usr/local/bin/emacs 是一个符号链接,它不指向 Emacs 二进制文件,而是指向一个 shell 脚本:

    $ ls -l /usr/local/bin/emacs
    lrwxr-xr-x  1 aki  staff  30 May 20  2013 /usr/local/bin/emacs -> ../Cellar/emacs/24.3/bin/emacs
    $ file /usr/local/Cellar/emacs/24.3/bin/emacs
    /usr/local/Cellar/emacs/24.3/bin/emacs: Bourne-Again shell script text executable
    $ cat /usr/local/Cellar/emacs/24.3/bin/emacs
    #!/bin/bash
    /usr/local/Cellar/emacs/24.3/Emacs.app/Contents/MacOS/Emacs -nw  "$@"
    

    我不知道为什么#!/path/to/a/shell/script 没有“做正确的事”。我对它进行了试验,它似乎只是将您的第一个脚本作为 shell 脚本运行,而不是像您期望的那样将脚本的名称作为参数传递给第一个脚本。也许一些 shell 向导可以对此发表评论?

    与此同时,这是可行的:

    #!/usr/local/Cellar/emacs/24.3/bin/emacs-24.3 --script
    (princ "hello world\n")
    

    因为这是正确的 Emacs 二进制文件的路径。我想你会想用env 或任何使这个便携的东西做一些废话。

    希望这可以帮助其他尝试在 Mac 上执行此操作的人。

    【讨论】:

    • Shebangs 由内核处理,细节可能是特定于操作系统的。但是,我认为以下内容抓住了所发生事情的本质。指定的路径将直接传递给系统调用execl(或可能是exec 系列的另一个成员),并将您的脚本名称作为其参数。如果 shebang 不是真正的可执行文件,execl 会失败,内核会退回到系统 shell 执行原始脚本。
    • 有趣。 FWIW,在 Ubuntu (12.04) 中不会出现此问题。
    猜你喜欢
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 2023-03-29
    • 2012-01-10
    • 2010-09-19
    • 2013-12-28
    • 2011-06-22
    相关资源
    最近更新 更多