2009-01-07 57 views
10

我想要做的是将文件中的设置包含到当前的交互式bash shell中,如下所示:bash脚本如何知道它在何时被安装的目录。运营商?

$。 /path/to/some/dir/.settings

问题是.settings脚本也需要使用“。”运营商包括这样的其他文件:

。 .extra_settings

如何在.settings文件中引用.extra_settings的相对路径?这两个文件始终存储在同一目录中,但根据安装这些文件的位置,此目录的路径将有所不同。

操作员总是知道/ path/to/some/dir /,如上所示。 .settings文件如何知道它的安装目录?我宁愿没有安装过程记录已安装目录的名称。

回答

17

衍生弹相信$(dirname "$BASH_SOURCE")会做你想要什么,只要你是采购文件是一个符号链接。

如果您正在输出可能是一个符号链接的文件,你可以这样做以下,以获得真正的目录:

PRG="$BASH_SOURCE" 
progname=`basename "$BASH_SOURCE"` 

while [ -h "$PRG" ] ; do 
    ls=`ls -ld "$PRG"` 
    link=`expr "$ls" : '.*-> \(.*\)$'` 
    if expr "$link" : '/.*' > /dev/null; then 
     PRG="$link" 
    else 
     PRG=`dirname "$PRG"`"/$link" 
    fi 
done 

dir=$(dirname "$PRG") 
+0

完美。 $(dirname“$ BASH_SOURCE”)就是我正在寻找的东西。为了我的目的,我不太关心符号链接。感谢所有的回应。这里真的很好的答案。 – Gary 2009-01-07 21:32:19

+8

要解析符号链接,你可以这样做:`dir = $(dirname $(readlink -f“$ BASH_SOURCE”))` – 2010-07-18 16:57:14

0

我尝试了$(dirname $ 0)的变体,但当.settings文件包含在“。”中时失败。如果我正在执行.settings文件而不是包含它,则此解决方案将起作用。相反,$(dirname $ 0)总是返回“。”,表示当前目录。当做这样的事情时会失败:

$ cd/ $。 /some/path/.settings

+0

嗯,太糟糕了。我不知道那么 – 2009-01-07 21:09:38

2

不同的问题 - 如果您使用的是“。”为了设置环境变量,这样做的另一个标准方法是让你的脚本回声变量设置命令,例如:

# settings.sh 
echo export CLASSPATH=${CLASSPATH}:/foo/bar 

然后EVAL输出:

eval $(/path/to/settings.sh) 

那怎么包,比如modules工作。这种方式也可以很容易地支持从SH(X=...; export X)和csh(setenv X ...

+0

对,这就是INN如何做到的。 “innconfvar”(我认为这就是所谓的)发出配置变量为sh,csh或perl命令。 – 2009-01-07 20:45:28

+0

我喜欢这个想法。但是,我没有使用它,因为副作用会使得.settings文件更难以阅读,因为它已经有了大量的转义符。见下文。 – Gary 2009-01-07 21:37:29

0

这类作品。它的工作原理是,你可以在.settings文件中使用$(dirname $ 0)语法来确定它的home,因为你在一个新shell中执行这个脚本。然而,它增加了在那里你需要改变线路,如卷积额外的一层:

export MYDATE=$(date) 

echo "export MYDATE=\$(date)" 

也许这是唯一的办法?

6

这里是什么可能是一个完美的解决方案:

script_dir=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd) 

这不会,但是,采购环节时的工作。在这种情况下,人们可能会做

script_dir=$(readlink -f $(readlink "${BASH_SOURCE[0]}") 

要洁具,像${array[x]}阵列POSIX不兼容。当然,BASH_SOURCE阵列仅在Bash中可用。