Linux 如何知道 Bash 脚本中的脚本文件名?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/192319/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:35:54  来源:igfitidea点击:

How do I know the script file name in a Bash script?

linuxbashshellscripting

提问by Ma99uS

How can I determine the name of the Bash script file inside the script itself?

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

Like if my script is in file runme.sh, then how would I make it to display "You are running runme.sh" message without hardcoding that?

就像我的脚本在 file 中一样runme.sh,那么我如何让它在没有硬编码的情况下显示“您正在运行 runme.sh”消息?

采纳答案by Tanktalus

me=`basename "
me="$(basename "$(test -L "
basename 
$ cat script.sh
#! /bin/sh
echo `basename 
echo $(basename $(readlink -nf 
$ ./s
0 is: ./s
BASH_SOURCE is: ./s
$ . ./s
0 is: bash
BASH_SOURCE is: ./s

$ cat s
#!/bin/bash

printf '
# ------------- SCRIPT ------------- #

#!/bin/bash

echo
echo "# arguments called with ---->  ${@}     "
echo "# $1 ---------------------->         "
echo "# $2 ---------------------->         "
echo "# path to me --------------->  ##代码##     "
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'
#  ---------------------->  'hello there'
#  ---------------------->  '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 ------------- #
is: %s\n$BASH_SOURCE is: %s\n' "##代码##" "$BASH_SOURCE"
))
` $ ./script.sh script.sh $ ln script.sh linktoscript $ ./linktoscript linktoscript
" && readlink "##代码##" || echo "##代码##")")"
"`

For reading through a symlink1, which is usually not what you want (you usually don't want to confuse the user this way), try:

要阅读符号链接1,这通常不是您想要的(您通常不想以这种方式混淆用户),请尝试:

##代码##

IMO, that'll produce confusing output. "I ran foo.sh, but it's saying I'm running bar.sh!? Must be a bug!" Besides, one of the purposes of having differently-named symlinks is to provide different functionality based on the name it's called as (think gzip and gunzip on some platforms).

IMO,这会产生令人困惑的输出。“我运行 foo.sh,但它说我正在运行 bar.sh!?一定是一个错误!” 此外,使用不同名称的符号链接的目的之一是根据它的名称提供不同的功能(想想某些平台上的 gzip 和 gunzip)。



1That is, to resolve symlinks such that when the user executes foo.shwhich is actually a symlink to bar.sh, you wish to use the resolved name bar.shrather than foo.sh.

1也就是说,要解析符号链接,以便当用户执行foo.sh实际上是指向 的符号链接时bar.sh,您希望使用解析的名称bar.sh而不是foo.sh

回答by mmacaulay

echo "You are running $0"

echo "你正在运行 $0"

回答by VolkA

You can use $0 to determine your script name (with full path) - to get the script name only you can trim that variable with

您可以使用 $0 来确定您的脚本名称(带完整路径) - 只有您可以使用

##代码##

回答by Josh Lee

If the script name has spaces in it, a more robust way is to use "$0"or "$(basename "$0")"- or on MacOS: "$(basename \"$0\")". This prevents the name from getting mangled or interpreted in any way. In general, it is good practice to always double-quote variable names in the shell.

如果脚本名称中包含空格,则更可靠的方法是使用"$0"or "$(basename "$0")"- 或在 MacOS 上:"$(basename \"$0\")". 这可以防止名称以任何方式被破坏或解释。通常,在 shell 中始终用双引号引用变量名是一种很好的做法。

回答by Chris Conway

$0doesn't answer the question (as I understand it). A demonstration:

$0没有回答这个问题(据我所知)。演示:

##代码##

How does one get ./linktoscriptto print out script.sh?

怎么./linktoscript打印出来script.sh

[EDIT] Per @ephemient in comments above, though the symbolic link thing may seem contrived, it is possible to fiddle with $0such that it does not represent a filesystem resource. The OP is a bit ambiguous about what he wanted.

[编辑] 根据上面评论中的@ephemient,尽管符号链接似乎是人为的,但可以摆弄$0它不代表文件系统资源。OP对他想要的东西有点含糊不清。

回答by Travis B. Hartwell

To answer Chris Conway, on Linux (at least) you would do this:

要回答Chris Conway,在 Linux 上(至少)你会这样做:

##代码##

readlink prints out the value of a symbolic link. If it isn't a symbolic link, it prints the file name. -n tells it to not print a newline. -f tells it to follow the link completely (if a symbolic link was a link to another link, it would resolve that one as well).

readlink 打印出符号链接的值。如果它不是符号链接,它会打印文件名。-n 告诉它不打印换行符。-f 告诉它完全跟随链接(如果符号链接是到另一个链接的链接,它也会解析那个链接)。

回答by Mr. Muskrat

If you want it without the path then you would use ${0##*/}

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

回答by Jim Dodd

These answers are correct for the cases they state but there is a still a problem if you run the script from another script using the 'source' keyword (so that it runs in the same shell). In this case, you get the $0 of the calling script. And in this case, I don't think it is possible to get the name of the script itself.

这些答案对于他们陈述的情况是正确的,但是如果您使用“source”关键字从另一个脚本运行脚本(以便它在同一个 shell 中运行),那么仍然存在问题。在这种情况下,您将获得调用脚本的 $0。在这种情况下,我认为不可能获得脚本本身的名称。

This is an edge case and should not be taken TOO seriously. If you run the script from another script directly (without 'source'), using $0 will work.

这是一个边缘情况,不应太认真。如果您直接从另一个脚本(没有“源”)运行脚本,则使用 $0 将起作用。

回答by Dimitre Radoulov

With bash >= 3the following works:

使用bash >= 3以下工作:

##代码##

回答by Bill Hernandez

##代码##