shell脚本可以告诉它所在的目录。没有bashisms

时间:2011-12-12 00:00:38

标签: shell sh

受到这个问题的启发。

Getting the source directory of a Bash script from within

是否有可能,但不需要bash。

我正在运行Ubuntu,在我从Bash问题中需要接受的解决方案之前,我的哈希爆炸是这样的

#!/bin/sh

我喜欢这样,是否有办法保持这种方式?

编辑:

它应该输出正确的目录,即使这样运行,

./script.sh

6 个答案:

答案 0 :(得分:4)

$(dirname -- "$0")怎么样?

如果你的shell只使用反引号,那就是:

`dirname -- "$0"`

答案 1 :(得分:3)

/bin/sh是一个与bourne兼容的shell(今天bashksh)。在这些代码中,以下代码行将为您提供当前运行脚本的绝对路径:

DIR=$( cd $( dirname -- "$0" ) > /dev/null ; pwd )

这一行有很多智慧:

  • 引号确保路径中的空格不会导致问题。
  • 不需要引号来保护$(...)的结果。如果你使用反引号,你需要更多的引号,但是今天几乎所有的shell都支持$(),因为反引号有很多问题。
  • $()具有在子shell中执行命令的良好副作用,因此当前路径不会改变。
  • --用于避免以-
  • 开头的路径出现问题
  • > /dev/null就在那里,因为cd可以打印当前路径,具体取决于shell选项。
  • 我正在使用dirname,因为其他所有功能都需要在任何地方都无法使用的特殊功能。这意味着一个进程必须分叉但是,这会发生一次。
  • pwd打印绝对路径

答案 2 :(得分:2)

mydir="${0%/*}"
if [ "$mydir" == "$0" ]; then
    echo "Indeterminate location."
    exit 1;
fi;

无需创建额外流程并致电dirname。在shell提示符(例如$ 0 ==“ - bash”)中直接运行它时,或者通过搜索$ PATH调用程序时,可能会发生不确定位置。 (然后$ 0也将没有斜线)

#optional addition
mydir=$(readlink -f "$0")

答案 3 :(得分:2)

如果不对其运行的系统做出假设,就不可能以可靠的方式做到这一点。这个bash wiki entry详细介绍了这个问题。

该页面提供了以下替代方案:

  

保持脚本的配置真的是最有意义的   单个静态位置,例如/etc/foobar.conf。如果你需要   定义多个配置文件,然后就可以拥有一个目录   (例如,/ var / lib / foobar /或/ usr / local / lib / foobar /),并读取   目录在固定位置的位置,例如/etc/foobar.conf。如果   你甚至不希望那么多硬编码,你可以通过   foob​​ar.conf(或您的配置目录本身)的位置为   脚本的参数。如果您需要脚本假定某些   在没有/etc/foobar.conf的情况下默认情况下,你可以输入默认值   脚本本身,或者回归到$ HOME / .foobar.conf之类的东西   如果缺少/etc/foobar.conf。在a上安装脚本时   在目标系统中,您可以将脚本的位置放入变量中   脚本本身。此时可以获得相关信息   只要脚本不移动,它将始终保持正确   每个安装的系统。在大多数情况下,中止更有意义   如果您的配置数据无法通过明显的方式找到,   而不是通过神秘的过程,并可能提出   错误的答案。

答案 4 :(得分:2)

就个人而言,我使用:

EXEC_DIR=$( readlink -f $( dirname -- "$0" ) )

在我的shell脚本中(/ bin / sh)。到目前为止对我来说还行。

答案 5 :(得分:2)

对于那些看过BASH DASH当前脚本文件夹的人。

<强> 1.sh

#!/bin/sh
if [ "$BASH_SOURCE" != "" ]
then
    DIR="$( cd "$( dirname "$BASH_SOURCE" )" && pwd )"
elif [ "$DASH_SOURCE" != "" ]
then
    DIR="$( cd "$( dirname "$DASH_SOURCE" )" && pwd )"
else
    DIR="$( cd "$( dirname "$0" )" && pwd )"
fi
echo $DIR

将产生以下内容:

cd ~
docker@boot2docker:~$ sh ./test/1.sh 
/home/docker/test
docker@boot2docker:~$ ./test/1.sh 
/home/docker/test
docker@boot2docker:~$ source ./test/1.sh 
/home/docker

如果有人知道如何处理source,请在下面发表评论。