linux - tutorial - unix shell




我如何知道Bash脚本中的脚本文件名? (14)

我如何确定脚本本身内的Bash脚本文件的名称?

就像如果我的脚本在文件runme.sh ,那么我将如何让它显示“你正在运行runme.sh”消息而不硬编码?


$0不回答这个问题(据我所知)。 示范:

$ cat script.sh
#! /bin/sh
echo `basename $0`
$ ./script.sh 
script.sh
$ ln script.sh linktoscript
$ ./linktoscript 
linktoscript

如何获得./linktoscript输出script.sh

[编辑]上面评论中的每个@ephemient,虽然符号链接的东西可能看起来有点麻烦,但可以摆弄$0这样它就不会代表文件系统资源。 OP对他想要的有点含糊不清。


$BASH_SOURCE在采购脚本时给出正确的答案。

但是,这包括路径,以便仅获取脚本文件名,请使用:

$(basename $BASH_SOURCE) 

回声“你正在运行$ 0”


回复:Tanktalus的(接受)上面的答案,稍微更简洁的方法是使用:

me=$(readlink --canonicalize --no-newline $0)

如果您的脚本来自另一个bash脚本,则可以使用:

me=$(readlink --canonicalize --no-newline $BASH_SOURCE)

我同意,如果您的目标是向用户提供反馈,那么解引用符号链接会很混乱,但有些情况下,您确实需要获取脚本或其他文件的规范名称,这是最好的方法。


如果你想要它没有路径,那么你会使用${0##*/}


如果你的调用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"

您可以使用$ 0来确定您的脚本名称(使用完整路径) - 只有您可以使用修剪该变量才能获取脚本名称

basename $0

感谢Bill Hernandez的信息。 我添加了一些我正在采用的偏好。

#!/bin/bash
function Usage(){
    echo " Usage: show_parameters [ arg1 ][ arg2 ]"
}
[[ ${#2} -eq 0 ]] && Usage || {
    echo
    echo "# arguments called with ---->  ${@}     "
    echo "# \$1 ----------------------->  $1       "
    echo "# \$2 ----------------------->  $2       "
    echo "# path to me --------------->  ${0}     " | sed "s/$USER/\$USER/g"
    echo "# parent path -------------->  ${0%/*}  " | sed "s/$USER/\$USER/g"
    echo "# my name ------------------>  ${0##*/} "
    echo
}

干杯


由于一些评论询问关于文件名没有扩展名,下面是一个例子如何实现:

FileName=${0##*/}
FileNameWithoutExtension=${FileName%.*}

请享用!


要回答克里斯康威 ,在Linux上(至少)你会这样做:

echo $(basename $(readlink -nf $0))

readlink输出一个符号链接的值。 如果它不是符号链接,则会打印文件名。 -n告诉它不要打印换行符。 -f指示它完全遵循链接(如果符号链接是另一个链接的链接,它也会解决该链接)。


随着bash> = 3 ,以下工作:

$ ./s
0 is: ./s
BASH_SOURCE is: ./s
$ . ./s
0 is: bash
BASH_SOURCE is: ./s

$ cat s
#!/bin/bash

printf '$0 is: %s\n$BASH_SOURCE is: %s\n' "$0" "$BASH_SOURCE"

# ------------- SCRIPT ------------- #

#!/bin/bash

echo
echo "# arguments called with ---->  ${@}     "
echo "# \$1 ---------------------->  $1       "
echo "# \$2 ---------------------->  $2       "
echo "# path to me --------------->  ${0}     "
echo "# parent path -------------->  ${0%/*}  "
echo "# my name ------------------>  ${0##*/} "
echo
exit

# ------------- CALLED ------------- #

# Notice on the next line, the first argument is called within double, 
# and single quotes, since it contains two words

$  /misc/shell_scripts/check_root/show_parms.sh "'hello there'" "'william'"

# ------------- RESULTS ------------- #

# arguments called with --->  'hello there' 'william'
# $1 ---------------------->  'hello there'
# $2 ---------------------->  'william'
# path to me -------------->  /misc/shell_scripts/check_root/show_parms.sh
# parent path ------------->  /misc/shell_scripts/check_root
# my name ----------------->  show_parms.sh

# ------------- END ------------- #

echo "$(basename "`test -L ${BASH_SOURCE[0]} \
                   && readlink ${BASH_SOURCE[0]} \
                   || echo ${BASH_SOURCE[0]}`")"

me=`basename "$0"`

对于通常不是你想要的符号链接(你通常不希望用这种方式混淆用户)来说,请尝试:

me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")"

国际海事组织,这将产生混乱的输出。 “我跑了foo.sh,但它说我正在运行bar.sh!?必须是一个bug!” 此外,具有不同名称符号链接的目的之一是根据其名称(在某些平台上认为gzip和gunzip)提供不同的功能。







scripting