如何确定脚本本身中的Bash脚本文件的名称?
就像如果我的脚本在文件runme.sh中,那么我如何让它显示“您正在运行runme.sh”消息而不硬编码?
如何确定脚本本身中的Bash脚本文件的名称?
就像如果我的脚本在文件runme.sh中,那么我如何让它显示“您正在运行runme.sh”消息而不硬编码?
当前回答
如果你调用shell脚本喜欢
/home/mike/runme.sh
$0是全名
/home/mike/runme.sh
Basename $0将获得基本文件名
runme.sh
你需要把这个基本的名字放到一个变量里,比如
filename=$(basename $0)
并添加额外的文本
echo "You are running $filename"
你的脚本就像
/home/mike/runme.sh
#!/bin/bash
filename=$(basename $0)
echo "You are running $filename"
其他回答
me=`basename "$0"`
对于读取symlink1,这通常不是你想要的(你通常不想以这种方式迷惑用户),尝试:
me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")"
在我看来,这会产生令人困惑的输出。“我跑了foo.sh,但它说我跑了bar.sh!?”一定是虫子!”此外,使用不同名称的符号链接的目的之一是根据其名称提供不同的功能(例如某些平台上的gzip和gunzip)。
1也就是说,为了解析符号链接,当用户执行foo.sh时,它实际上是一个到bar.sh的符号链接,你希望使用解析的名称bar.sh而不是foo.sh。
由于一些注释询问没有扩展名的文件名,这里有一个示例如何完成:
FileName=${0##*/}
FileNameWithoutExtension=${FileName%.*}
享受吧!
在所有情况下获取脚本或源脚本的“真实路径”:
fullname=$(readlink $0) # Take care of symbolic links
dirname=${fullname%/*} # Get (most of the time) the dirname
realpath=$(dirname $BASH_SOURCE) # TO handle sourced scripts
[ "$realpath" = '.' ] && realpath=${dirname:-.}
下面是要生成的bash脚本(在新创建的“workdir”子目录中,在当前目录的“mytest”中),该bash脚本将派生另一个脚本,该脚本将调用bash定义的函数....测试了许多方法来启动它们:
#!/bin/bash
##############################################################
ret=0
fullname=$(readlink $0) # Take care of symbolic links
dirname=${fullname%/*} # Get (most of the time) the dirname
realpath=$(dirname $BASH_SOURCE) # TO handle sourced scripts
[ "$realpath" = '.' ] && realpath=${dirname:-.}
fullname_withoutextension=${fullname%.*}
mkdir -p workdir
cat <<'EOD' > workdir/_script_.sh
#!/bin/bash
##############################################################
ret=0
fullname=$(readlink $0) # Take care of symbolic links
dirname=${fullname%/*} # Get (most of the time) the dirname
realpath=$(dirname $BASH_SOURCE) # TO handle sourced scripts
[ "$realpath" = '.' ] && realpath=${dirname:-.}
fullname_withoutextension=${fullname%.*}
echo
echo "# ------------- RESULTS ------------- #"
echo "# path to me (\$0)-----------> ${0} "
echo "# arguments called with ----> ${@} "
echo "# \$1 -----------------------> $1 "
echo "# \$2 -----------------------> $2 "
echo "# path to me (\$fullname)----> ${fullname} "
echo "# parent path(\${0%/*})------> ${0%/*} "
echo "# parent path(\$dirname)-----> ${dirname} "
echo "# my name ----\${0##*/}------> ${0##*/} "
echo "# my source -\${BASH_SOURCE}-> ${BASH_SOURCE} "
echo "# parent path(from BASH_SOURCE) -> $(dirname $BASH_SOURCE)"
echo "# my function name -\${FUNCNAME[0]}------> ${FUNCNAME[0]}"
echo "# my source or script real path (realpath)------------------> $realpath"
echo
[ "$realpath" = "workdir" ] || ret=1
[ $ret = 0 ] || echo "*******************************************************"
[ $ret = 0 ] || echo "*********** ERROR **********************************"
[ $ret = 0 ] || echo "*******************************************************"
show_params () {
echo
echo "# --- RESULTS FROM show_params() ---- #"
echo "# path to me (\$0)-----------> ${0} "
echo "# arguments called with ----> ${@} "
echo "# \$1 -----------------------> $1 "
echo "# \$2 -----------------------> $2 "
echo "# path to me (\$fullname)----> ${fullname} "
echo "# parent path(\${0%/*})------> ${0%/*} "
echo "# parent path(\$dirname)-----> ${dirname} "
echo "# my name ----\${0##*/}------> ${0##*/} "
echo "# my source -\${BASH_SOURCE}-> ${BASH_SOURCE} "
echo "# parent path(from BASH_SOURCE) -> $(dirname $BASH_SOURCE)"
echo "# my function name -\${FUNCNAME[0]}------> ${FUNCNAME[0]}"
echo "# my source or script real path (realpath)------------------> $realpath"
echo
[ "$realpath" = "workdir" ] || ret=1
[ $ret = 0 ] || echo "*******************************************************"
[ $ret = 0 ] || echo "*********** ERROR **********************************"
[ $ret = 0 ] || echo "*******************************************************"
}
show_params "$@"
EOD
cat workdir/_script_.sh > workdir/_side_by_side_script_sourced.inc
cat <<'EOD' >> workdir/_script_.sh
echo "# . $realpath/_side_by_side_script_sourced.inc 'hello there' 'william'"
. $realpath/_side_by_side_script_sourced.inc 'hello there' 'william'
[ $ret = 0 ] || echo "*******************************************************"
[ $ret = 0 ] || echo "*********** ERROR **********************************"
[ $ret = 0 ] || echo "*******************************************************"
EOD
chmod +x workdir/_script_.sh
[ -L _mytest_ ] && rm _mytest_
ln -s workdir/_script_.sh _mytest_
# ------------- CALLED ------------- #
called_by () {
echo '=========================================================================='
echo " Called by : " "$@"
echo '=========================================================================='
eval "$@"
}
called_by bash _mytest_
called_by ./_mytest_
called_by bash workdir/_script_.sh
called_by workdir/_script_.sh
called_by . workdir/_script_.sh
# ------------- RESULTS ------------- #
echo
echo
[ $ret = 0 ] || echo "*******************************************************"
[ $ret = 0 ] || echo "*********** ERROR **********************************"
[ $ret = 0 ] || echo "*******************************************************"
echo
[ $ret = 0 ] && echo ".... location of scripts (\$realpath) should always be equal to $realpath, for all test cases at date".
echo
# ------------- END ------------- #
如果脚本名中有空格,更可靠的方法是使用"$0"或"$(basename "$0")"-或MacOS: "$(basename \"$0\")"。这可以防止名称以任何方式被破坏或解释。一般来说,在shell中始终使用双引号作为变量名是一种良好的实践。
$BASH_SOURCE在获取脚本时给出正确答案。
然而,这包括路径,所以只获得脚本文件名,使用:
$(basename $BASH_SOURCE)