在Mac上检查Shell脚本文件是否存在的问题

3

好的,我已经在Linux Ubuntu中编写了一个.sh文件,它运行得非常完美。然而,在Mac上,即使它在同一目录下,它总是返回文件未找到的错误。有人能帮我解决吗?

.sh文件:

if [ ! -f file-3*.jar ]; then
echo "[INFO] jar could not be found."
exit
fi

我想补充一下,这不是针对多个文件的,而是针对一个文件改名为多个结尾。


1
你能展示一下 ls file-3*.jar 的输出吗? - larsks
请阅读下面的答案,我正在将其变为可执行文件并在终端中运行。 - Ciphor
你能否发布整个脚本(包括shebang)以及运行时使用的实际命令行? - Paul R
这是我的脚本,实际上是将脚本编译成jar文件的 :) - Ciphor
它应该从 cd ~/Documents/RSBot 运行。 - Ciphor
显示剩余6条评论
4个回答

1
在对@Paul R的回答发表评论时,您说:“shell脚本也在与jar文件相同的目录中。因此,他们可以将SH文件分配给默认情况下使用终端打开后,双击它。”我怀疑这就是问题所在——当您通过双击运行shell脚本时,它会以用户主目录为工作目录运行,而不是脚本所在的目录。您可以通过让脚本cd到它所在的目录来解决这个问题:
cd "$(dirname "$BASH_SOURCE")"

编辑:$BASH_SOURCE 当然是bash扩展,不适用于其他shell。如果您的脚本不能保证在bash中运行,请改用以下方法:

case "$0" in
    */*)
        cd "$(dirname "$0")" ;;
    *)
        me="$(which "$0")"
        if [ -n "$me" ]; then
            cd "$(dirname "$me")"
        else
            echo "Can't locate script directory" >&2
            exit 1
        fi ;;
esac

顺便说一下,构造函数[ ! -f file-3*.jar ]让我感到有些紧张,因为如果有多个匹配的文件,它会出现奇怪的错误。 (我知道,这不应该发生; 但是那些不应该发生的事情总是有令人烦恼的倾向发生。)我会使用这个代替:

matchfiles=(file-3*.jar)
if [ ! -f "${matchfiles[0]}" ]; then
    ...

如果您无法依赖于Bash扩展,这里有一个替代方案,可以在任何POSIX shell中使用:

if [ ! -f "$(echo file-3*.jar)" ]; then

请注意,如果有多个匹配项,则此操作将失败(即表现为文件不存在)。

嗯...如果这个可行,我会告诉你的。另外,我不知道在sh中是否有BASH_SOURCE可用? - Ciphor
不错,我在假设是bash。在纯POSIX shell中找到脚本所在的目录就比较麻烦了(而我展示的matchfiles技巧也行不通)。 - Gordon Davisson

0

不是因为它不能为你工作,而是不能为你的用户工作吗?多年来,OS X 的默认 shell 已经发生了变化(参见this post) - 但是看起来你的评论说你已经放置了 #!

你确定你的用户将 JAR 文件放在了正确的位置吗?也许脚本不是错的,而是在告诉你正确的答案 - 脚本所在的位置缺少必需的文件。


嗯...是的,当我看到你的观点时,我试图帮助他们,但他们坚持认为两个文件在同一个目录中。我应该尝试将其转换为BASH或其他什么吗? - Ciphor
输出脚本运行的路径,并查看它是否与用户认为的相匹配。如果您能走到其中一个用户身边并观察他们的操作,以了解发生了什么,那就更好了。 - AlG

0

我认为问题在别处,因为脚本在 Mac OS X 上按预期工作:

$ if [ ! -f file-3*.jar ]; then echo "[INFO] jar could not be found."; fi
[INFO] jar could not be found.
$ touch file-302.jar
$ if [ ! -f file-3*.jar ]; then echo "[INFO] jar could not be found."; fi
$

也许你的脚本正在错误的shell下运行,或者在错误的工作目录下运行?


这是 #!/bin/sh,他们被指示对文件进行 chmod +x 操作。Shell 脚本也位于与 jar 文件相同的目录中。因此,他们可以将 SH 文件分配为默认使用终端打开后,双击它即可。 - Ciphor
完全不理解:/ - Ciphor
将shebang更改为#!/usr/bin/env sh怎么样? - Ciphor

0

这不是一个答案,而是一种策略:考虑进行严格的日志记录。将诸如"[INFO] jar could not be found."之类的回显消息同时输出到屏幕和日志文件中,然后添加额外的日志记录,例如$PWD$SHELL$0的值。这样,当您的客户/同事尝试运行脚本并失败时,他们可以将日志发送给您。

我可能会使用类似于以下的东西:

screenlog() {
    echo "$*"
    echo "$*" >> $LOGFILE
}

log() {
    echo "$*" >> $LOGFILE
}

在你的脚本顶部定义$LOGFILE。然后在你的脚本中添加类似screenlog "[INFO] jar could not be found."log "\$PWD: $PWD"的语句。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接