从内部获取Bash脚本的源目录
如何在该脚本中获取Bash脚本所在的目录的路径?
例如,假设我想使用Bash脚本作为另一个应用程序的启动器。 我想将工作目录更改为Bash脚本所在的目录,因此我可以对该目录中的文件进行操作,如下所示:
$ ./application
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
是一个有用的单行程序,无论它从哪里被调用,它都会给你脚本的完整目录名称。
只要用于查找脚本的路径的最后一个组件不是符号链接(目录链接正常),它就会工作。 如果您还想解析脚本本身的任何链接,则需要一个多线解决方案:
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
最后一个可以与别名, source
, bash -c
,符号链接等组合使用。
请注意:如果您cd
运行该段之前到不同的目录,其结果可能是不正确的! 另外,请注意$CDPATH
陷阱。
要了解它如何工作,请尝试运行这个更详细的表单:
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
TARGET="$(readlink "$SOURCE")"
if [[ $TARGET == /* ]]; then
echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'"
SOURCE="$TARGET"
else
DIR="$( dirname "$SOURCE" )"
echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')"
SOURCE="$DIR/$TARGET" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
fi
done
echo "SOURCE is '$SOURCE'"
RDIR="$( dirname "$SOURCE" )"
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
if [ "$DIR" != "$RDIR" ]; then
echo "DIR '$RDIR' resolves to '$DIR'"
fi
echo "DIR is '$DIR'"
它会打印如下内容:
SOURCE './scriptdir.sh' is a relative symlink to 'sym2/scriptdir.sh' (relative to '.')
SOURCE is './sym2/scriptdir.sh'
DIR './sym2' resolves to '/home/ubuntu/dotfiles/fo fo/real/real1/real2'
DIR is '/home/ubuntu/dotfiles/fo fo/real/real1/real2'
使用dirname "$0"
:
#!/bin/bash
echo "The script you are running has basename `basename "$0"`, dirname `dirname "$0"`"
echo "The present working directory is `pwd`"
如果您没有从包含它的目录运行脚本,单独使用pwd
将不起作用。
[matt@server1 ~]$ pwd
/home/matt
[matt@server1 ~]$ ./test2.sh
The script you are running has basename test2.sh, dirname .
The present working directory is /home/matt
[matt@server1 ~]$ cd /tmp
[matt@server1 tmp]$ ~/test2.sh
The script you are running has basename test2.sh, dirname /home/matt
The present working directory is /tmp
dirname命令是最基本的,只需将$ 0(脚本名称)变量之外的路径解析为文件名即可:
dirname "$0"
但是,正如马特b指出的那样,根据脚本的调用方式,返回的路径是不同的。 pwd不做这项工作,因为它只告诉你当前目录是什么,而不是脚本所在的目录。另外,如果执行到脚本的符号链接,你将得到一个(可能是相对的)路径到链接所在的位置,而不是实际的脚本。
其他一些人提到了readlink命令,但最简单的方法是,您可以使用:
dirname "$(readlink -f "$0")"
readlink会将脚本路径解析为文件系统根目录的绝对路径。 因此,包含单点或双点,波浪线和/或符号链接的任何路径都将被解析为完整路径。
下面是一个脚本,演示其中的每一个, whatdir.sh:
#!/bin/bash
echo "pwd: `pwd`"
echo "$0: $0"
echo "basename: `basename $0`"
echo "dirname: `dirname $0`"
echo "dirname/readlink: $(dirname $(readlink -f $0))"
在我的主目录中运行此脚本,使用相对路径:
>>>$ ./whatdir.sh
pwd: /Users/phatblat
$0: ./whatdir.sh
basename: whatdir.sh
dirname: .
dirname/readlink: /Users/phatblat
再次,但使用脚本的完整路径:
>>>$ /Users/phatblat/whatdir.sh
pwd: /Users/phatblat
$0: /Users/phatblat/whatdir.sh
basename: whatdir.sh
dirname: /Users/phatblat
dirname/readlink: /Users/phatblat
现在改变目录:
>>>$ cd /tmp
>>>$ ~/whatdir.sh
pwd: /tmp
$0: /Users/phatblat/whatdir.sh
basename: whatdir.sh
dirname: /Users/phatblat
dirname/readlink: /Users/phatblat
最后使用符号链接来执行脚本:
>>>$ ln -s ~/whatdir.sh whatdirlink.sh
>>>$ ./whatdirlink.sh
pwd: /tmp
$0: ./whatdirlink.sh
basename: whatdirlink.sh
dirname: .
dirname/readlink: /Users/phatblat
链接地址: http://www.djcxy.com/p/183.html
上一篇: Getting the source directory of a Bash script from within