【问题标题】:Double Clicking a shell script on Mac在 Mac 上双击 shell 脚本
【发布时间】:2017-12-11 19:42:43
【问题描述】:

我有一个运行 jar 文件的小脚本:

#!/bin/bash

prefix="foo";
name=`ls ${prefix}*.jar`;
echo $name;
java -jar $name prop1.properties prop2.properties

当我使用 ./myscript.sh 在终端中运行它时,它工作正常并且 jar 文件执行,但是当我在 myscript.command 中重命名它并双击它时,我有这个错误:

ls: foo*.jar : No such file or directory

我看到一个 .command 文件显然在根目录打开了一个终端,所以我尝试使用它找到包含 myscript.command 的目录:

dir = 'find <dir> -maxdepth 1 -type d -name '*myDirContainingJar*' -print -quit'
cd $dir

但是 dir 只是空白,有什么想法吗???

【问题讨论】:

  • dir = ... 命令不起作用有 3 个原因: 1) = 周围的空格意味着 shell 不会将其视为分配(它被视为 dir 命令, = 作为它的第一个参数)。 2) find 命令周围的单引号意味着它将被视为字符串而不是命令;你想要反引号或$( )$( ) 是首选)。并且 3) 可能有多个目录与该模式匹配,并且它不会可靠地选择正确的目录。

标签: macos shell


【解决方案1】:

您的脚本的问题在于它运行的工作目录 与您测试时使用的不同。当您在脚本中执行ls something 时,脚本会在当前工作目录中查找(如果您在终端中,您最后cded),不是在脚本所在的目录中通常,在编写这样的脚本时,您应该使用所引用文件的完整路径或找出脚本的目录并指向相对于该文件的文件。 One solution 在 Bash 中有效,但它可能不在您使用的 shell 中。

【讨论】:

    【解决方案2】:

    在 macOS 上从 Finder 中打开 shell 脚本(无论是扩展名为 .command 还是无扩展名的可执行 shell 脚本)创建当前用户的 主目录 em> 当前目录(从 macOS 10.12 开始)。

    要在bash 脚本中显式更改到脚本本身所在的目录,请使用:

    cd -- "$(dirname -- "$BASH_SOURCE")"
    

    在此调用场景中,以下符合 POSIX 的变体(使用 $0 代替 $BASH_SOURCE)也可以工作:cd -- "$(dirname -- "$0")"

    注意:

    • 一般,如果您的脚本是通过 符号链接 调用的,并且您想要更改到 目标 的目录(实际脚本文件的目录而不是符号链接所在的目录),需要做更多的工作 - 请参阅我的 this answer

    • 但是,当从 Finder 打开脚本时,此问题不适用,因为 Finder 本身 会解析指向其(最终)目标的符号链接,然后调用直接瞄准目标。

    【讨论】:

    • 我不明白你通过符号链接调用是什么意思?
    • @Sech: Re symlink: 假设你的脚本是~/foo,你在/usr/local/bin:ln -s ~/foo /usr/local/bin/foo中创建了一个指向它的符号链接。然后,当您从/usr/local/bin 而不是从~ 调用foo 时,上述命令将更改为/usr/local/bin