从符号链接运行 bash 脚本。如何更改目录以使相对目录起作用

从符号链接运行 bash 脚本。如何更改目录以使相对目录起作用

关于情况:

mycommand我有一个名为in的符号链接$PATH。它链接到其他地方调用的文件mycommand.sh。该文件需要另一个文件,我们称之为mycommand2.sh

somedir
|-mycommand.sh
|-mycommand2.sh

直接运行./mycommand.sh发现其他文件。运行时则mycommand不然。原因:在mycommand.sh另一个文件中称为./mycommand2.sh.

如何mycommand在不将所有相对目录更改为绝对目录的情况下工作?

答案1

该问题不是由符号链接引起的。

如果mycommand.sh调用./mycommand2.sh,它期望其当前工作目录是somedir.当前工作目录与命令的命名或调用方式无关。它是通过chdir()系统调用或cdshell 中的内置命令设置的进程属性。

如果你这样做:

cd /path/to/somedir
mycommand

mycommand又名mycommand.sh仍然会./mycommand2.sh在当前目录中找到。

为了mycommand.sh查找mycommand2.sh无论从哪个工作目录调用它,都需要进行如下修改:

#! /bin/sh -
mydir=$(dirname -- "$0")
"${mydir%/}/mycommand2.sh"

或者如果mycommand.sh确实需要其工作目录为somedir

#! /bin/sh -
mydir=$(dirname -- "$0")
CDPATH= cd -P -- "$mydir" || exit

./mycommand2.sh

这就是使用符号链接会导致问题的时候,就好像调用 as 一样mycommanddirname -- "$0"会返回符号链接的目录名mycommand,而不是脚本的目录名mycommand.sh

要解决这个问题,您需要修改mycommand.sh为:

#! /bin/sh -
mydir=$(dirname -- "$(readlink -f -- "$0")")
"${mydir%/}/mycommand2.sh"

其中readlink -f(不是标准命令,但很常见)将解析所有符号链接。这假设mycommand.sh它本身不是到不同目录中的脚本的符号链接。

如果您不能或不愿意修改该脚本,另一种方法是创建一个mycommand 脚本代替符号链接这样做:

#! /bin/sh -
cd /path/to/somedir &&
  exec ./mycommand.sh "$@"

相关内容