我有以下问题,我的 shell 脚本包含类似以下内容:
mydir=''
# config load
source $mydir/config.sh
.... execute various commands
我的脚本放置在我的用户目录中..比方说/home/bob/script.sh
如果我在/home/bob
目录内并运行./script.sh
一切正常。
如果我在外面并且想要使用绝对路径,则/home/bob/script.sh
无法正确调用 config.sh 文件。
$mydir
为了使脚本可以从每个路径轻松运行,我应该分配什么值?
mydir=$(which command?)
PS:作为奖励,如果脚本目录位于 $PATH 内,请提供替代方案
答案1
该$0
变量包含脚本的路径:
$ cat ~/bin/foo.sh
#!/bin/sh
echo $0
$ ./bin/foo.sh
./bin/foo.sh
$ foo.sh
/home/terdon/bin/foo.sh
$ cd ~/bin
$ foo.sh
./foo.sh
正如您所看到的,输出取决于它的调用方式,但它总是返回相对于脚本执行方式的脚本路径。因此,您可以这样做:
## Set mydir to the directory containing the script
## The ${var%pattern} format will remove the shortest match of
## pattern from the end of the string. Here, it will remove the
## script's name,. leaving only the directory.
mydir="${0%/*}"
# config load
source "$mydir"/config.sh
如果该目录在您的 中$PATH
,事情就更简单了。你可以跑source config.sh
。默认情况下,source
将在目录中查找文件$PATH
并获取找到的第一个文件:
$ help source
source: source filename [arguments]
Execute commands from a file in the current shell.
Read and execute commands from FILENAME in the current shell. The
entries in $PATH are used to find the directory containing FILENAME.
If any ARGUMENTS are supplied, they become the positional parameters
when FILENAME is executed.
如果您确定您的内容config.sh
是唯一的,或者至少是在 中找到的第一个$PATH
,您可以直接获取它。但是,我建议您不要这样做,而坚持使用第一种方法。你永远不知道什么时候另一个人config.sh
可能会出现在你的$PATH
。
答案2
这个方法是仅有的有用在bash脚本。
使用:
mydir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )"
怎么运行的:
BASH_SOURCE
FUNCNAME
是一个数组变量,其成员是源文件名,其中定义了数组变量中相应的 shell 函数名称。
所以,与:
cd "$( dirname "${BASH_SOURCE[0]}" )"
您移动到放置脚本的目录。
然后, 的输出cd
被发送到/dev/null
,因为有时,它会向 STDOUT 打印一些内容。例如,如果你$CDPATH
有.
最后,它执行:
pwd
获取当前位置。
来源:
答案3
找到了解决方案:
mydir=$(dirname "$0")
这样,就可以从任何地方调用脚本而不会出现任何问题。
答案4
尝试一下这个经测试并验证了外壳检查解决方案:
mydir="$(dirname "${0}")"
source "${mydir}"/config.sh
printf "read value of config_var is %s\n" "${config_var}"
考试:
$ ls
script.sh
config.sh
$ cat script.sh
#!/bin/bash --
mydir="$(dirname "${0}")"
source "${mydir}"/config.sh
printf "read value of config_var is %s\n" "${config_var}"
$ cat config.sh
config_var=super_value
$ mkdir "$(printf "\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\40\41\42\43\44\45\46\47testdir" "")"
$ mv *.sh *testdir
$ *testdir/script.sh
read value of config_var is super_value