我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
当前回答
我想确保剧本在其目录中运行。
cd $(dirname $(which $0) )
接下来,如果你真的想知道你在哪里运行,然后运行下面的命令。
DIR=$(/usr/bin/pwd)
其他回答
我认为最简单的答案是原始变量的参数扩展:
#!/usr/bin/env bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
echo "opt1; original answer: $DIR"
echo ''
echo "opt2; simple answer : ${BASH_SOURCE[0]%/*}"
它应该产生产量如:
$ /var/tmp/test.sh
opt1; original answer: /var/tmp
opt2; simple answer : /var/tmp
变量/参数扩展 ${BASH_SOURCE[0]%/*}”似乎更容易保持。
以下是获取脚本信息的简短方式:
文件和文件:
Script: "/tmp/src dir/test.sh"
Calling folder: "/tmp/src dir/other"
使用这些命令:
echo Script-Dir : `dirname "$(realpath $0)"`
echo Script-Dir : $( cd ${0%/*} && pwd -P )
echo Script-Dir : $(dirname "$(readlink -f "$0")")
echo
echo Script-Name : `basename "$(realpath $0)"`
echo Script-Name : `basename $0`
echo
echo Script-Dir-Relative : `dirname "$BASH_SOURCE"`
echo Script-Dir-Relative : `dirname $0`
echo
echo Calling-Dir : `pwd`
我得到了这个结果:
Script-Dir : /tmp/src dir
Script-Dir : /tmp/src dir
Script-Dir : /tmp/src dir
Script-Name : test.sh
Script-Name : test.sh
Script-Dir-Relative : ..
Script-Dir-Relative : ..
Calling-Dir : /tmp/src dir/other
此分類上一篇: https://pastebin.com/J8KjxrPF
這是我多年來創造的,用作我的Bash寫作的標題:
## BASE BRAIN - Get where you're from and who you are.
MYPID=$$
ORIGINAL_DIR="$(pwd)" # This is not a hot air balloon ride..
fa="$0" # First Assumption
ta= # Temporary Assumption
wa= # Weighed Assumption
while true; do
[ "${fa:0:1}" = "/" ] && wa=$0 && break
[ "${fa:0:2}" = "./" ] && ta="${ORIGINAL_DIR}/${fa:2}" && [ -e "$ta" ] && wa="$ta" && break
ta="${ORIGINAL_DIR}/${fa}" && [ -e "$ta" ] && wa="$ta" && break
done
SW="$wa"
SWDIR="$(dirname "$wa")"
SWBIN="$(basename "$wa")"
unset ta fa wa
( [ ! -e "$SWDIR/$SWBIN" ] || [ -z "$SW" ] ) && echo "I could not find my way around :( possible bug in the TOP script" && exit 1
此时此刻,您的变量 SW、SWDIR 和 SWBIN 包含您需要的内容。
下面是一个命令,在Bash或zsh下工作,以及是否单独执行或源:
[ -n "$ZSH_VERSION" ] && this_dir=$(dirname "${(%):-%x}") \
|| this_dir=$(dirname "${BASH_SOURCE[0]:-$0}")
它是如何工作的
Fallback 替代操作员:
% x=ok
% echo "${x}"
ok
% echo "${x:-fallback}"
ok
% x=
% echo "${x:-fallback}"
fallback
% y=yvalue
% echo "${x:-$y}"
yvalue
此分類上一篇: %x prompt escape code
接下来,我们将引入即时逃避代码,一个 zsh-only 功能. 在 zsh 中, %x 将扩展到文件的路径,但通常只有在进行即时行扩展时。
% cat apath/test.sh
fpath=%x
echo "${(%)fpath}"
% source apath/test.sh
apath/test.sh
% cd apath
% source test.sh
test.sh
% cat test.sh
echo "${(%):-%x}"
% source test.sh
test.sh
请注意,我们通常会把变量名称放在(%)和(%)之间,但我们留下了白色。
我们可能已经使用打印 -P %x 以获得相同的文件路径,有更少的黑客,但在我们的情况下,我们需要将其作为一个论点转到一个字符串,这将需要一个开始一个新的字符串的顶部:
% cat apath/test.sh
dirname "$(print -P %x)" # $(...) runs a command in a new process
dirname "${(%):-%x}"
% source apath/test.sh
apath
apath
显然,黑客的方式既更有效又更简短。
dirname ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
如果您想跟随同步链接,请使用您上面的路径上的阅读链接,重复或非重复。
#
# Location: test1/test2/test_script.sh
#
echo $0
echo $_
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
cur_file="${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
cur_dir="$(dirname "${cur_file}")"
source "${cur_dir}/func_def.sh"
function test_within_func_inside {
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
}
echo "Testing within function inside"
test_within_func_inside
echo "Testing within function outside"
test_within_func_outside
#
# Location: test1/test2/func_def.sh
#
function test_within_func_outside {
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
}
BASH - 来源
一个序列变量,其成员是源文件名,在 FUNCNAME序列变量中定义了相应的序列函数名称。
功能
这个变量可以使用 BASH_LINENO 和 BASH_SOURCE. FUNCNAME 的每个元素都有相应的元素在 BASH_LINENO 和 BASH_SOURCE 描述呼叫板. 例如, ${FUNCNAME[$i]} 被呼叫从文件 ${BASH_SOURCE[$i+1]} 到线号 ${BASH_LINENO[$i]}。
(源:Bash手册)