我正在写一个bash脚本.我需要当前的工作目录始终是脚本所在的目录.
默认行为是脚本中的当前工作目录是我运行它的shell的目录,但我不想要这种行为.
#!/bin/bash cd "$(dirname "$0")"
以下也有效:
cd "${0%/*}"
语法中充分地阐述这个 StackOverflow的答案.
尝试以下简单的单行:
适用于所有UNIX/OSX/Linux
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
注意:命令中使用双短划线( - )表示命令选项的结束,因此包含短划线或其他特殊字符的文件不会破坏命令.
对于Linux,Mac和其他*BSD:
dir=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)
白色空间支持:
cd "$(dirname "$(realpath "$0")")";
注意:${BASH_SOURCE[0]}
默认情况下应该安装在最流行的Linux发行版中(比如Ubuntu),但在某些情况下它可能会丢失,所以你必须安装它.
否则你可以尝试类似的东西(它将使用第一个现有的工具):
cd "$(dirname "$(readlink -f "$0" || realpath "$0")")"
对于Linux特定:
cd "$(dirname "$(readlink -f "$0")")"
在*BSD/Mac上使用GNU readlink:
cd "$(dirname "$(greadlink -f "$0")")"
注意:您需要$0
安装(例如1.安装Homebrew,2.source
).
在bash中
在bash中,您可以使用参数扩展来实现这一点,例如:
cd "${0%/*}"
但如果脚本从同一目录运行,则它不起作用.
或者,您可以在bash中定义以下函数:
realpath () { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" }
此函数需要1个参数.如果参数已经是绝对路径,则按原样打印,否则打印.
变量+文件名参数(不带realpath
前缀).
或者这是从Debian ${BASH_SOURCE[0]}
文件中获取的版本:
function realpath() { f=$@ if [ -d "$f" ]; then base="" dir="$f" else base="/$(basename "$f")" dir=$(dirname "$f") fi dir=$(cd "$dir" && /bin/pwd) echo "$dir$base" }
有关:
如何检测我运行shell脚本的当前目录?
从内部获取Bash脚本的源目录
使用OSX的Bash脚本绝对路径
bash脚本可靠的方式来获取自己的完整路径?
也可以看看:
如何在Mac上获取GNU的readlink -f的行为?
cd "$(dirname "${BASH_SOURCE[0]}")"
这很简单.有用.
对于没有在其他地方进行符号链接(例如)的脚本,可接受的答案很好用$PATH
。
#!/bin/bash cd "$(dirname "$0")"
但是,如果脚本是通过符号链接运行的,
ln -sv ~/project/script.sh ~/bin/; ~/bin/script.sh
这将进入~/bin/
目录,而不是~/project/
目录cd ,如果的目的cd
是包括相对于Windows的依赖关系,则可能会破坏脚本。~/project/
symlink安全答案如下:
#!/bin/bash cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
readlink -f
需要解析潜在的符号链接文件的绝对路径。
需要使用引号来支持可能包含空格的文件路径(不好的做法,但不能肯定不会出现这种情况)