使shell脚本对于它们被调用的位置是健壮的

时间:2013-08-24 22:12:57

标签: linux bash shell zsh ksh

编写一个shell脚本的最佳方法是什么,它将访问相对于它的文件,这样我从哪里调用它并不重要? “简单”意味着最简单/推荐的方式可以在不同的系统/ shell中使用。

示例

假设我有一个包含子文件夹~/MyProjectscripts/的文件夹files/。在scripts/中,我有一个想要访问foo.sh中文件的shell脚本files/

if [ -f "../files/somefile.ext" ]; then
    echo "File found"
else
    echo "File not found"
fi

如果我做cd ~/MyProject/scripts && ./foo.sh,它会正常工作,但它会因cd ~/MyProject && scripts/foo.sh而失败。

6 个答案:

答案 0 :(得分:3)

您通常可以这样做:

mydir="$(dirname $0)"

获取正在运行的脚本的目录。

然后使用它来找到你的文件。

答案 1 :(得分:1)

使所有路径绝对。 尽可能使用环境变量,例如$ HOME。 您遇到了UNIX脚本的弱点。

使用.profile或.bash_profile,您的开发人员可以设置一堆ENV变量。然后您的脚本可以使用这些变量。

在我工作的其中一个地方,您可以运行一个脚本,它会提示您想要查看哪个版本,并设置ENV,以便开发人员交互非常无缝。

答案 2 :(得分:0)

不确定它是否足够简单,但这可以为您提供解决方案:

Shell Script Loader

答案 3 :(得分:0)

if [ -f "../files/somefile.ext"]
then
  echo "file was found"
else
  echo "file was not found"
fi

第二

if [ ! -f /tmp/foo.txt ]; then
    echo "File not found!"
fi

答案 4 :(得分:0)

考虑到$0应该包含执行脚本的路径,你可以简单地cd到它然后正常处理

所以你只需要做

scriptDir=$(dirname -- "$0")
cd -- "$scriptDir"

但这仍然是一个黑客,你可能应该想办法使用绝对路径

答案 5 :(得分:0)

不幸的是,似乎没有一个真正通用的解决方案。我个人的建议(和实践)是只为那些提供一致访问权限的shell编写 - 最近的ksh93 ${.sh.file} bash $BASH_SOURCEzsh等。 (我不知道[[ -e myscript ]]解决方案,但我确定有一个。)

除此之外,最好的解决方案是以某种方式避免问题;例如,对于git存储库中脚本的示例,您可能要求从其所在的目录中调用脚本。通过检查{{1}}验证后,您可以预期相对链接将按预期工作。 (是的,为了完全健壮,你需要将脚本的基本名称硬编码到测试中,出于同样的原因,首先存在这个问题 - 在所有可能的情况下它都可用于shell。)