Bash $0 does not match command used at terminal
在我编写的bash脚本中,我试图打印一些信息给用户(作为对特定错误的响应),建议他们在命令中添加一个开关。我以为
我发现,当我从相对路径调用该脚本时,如/script.sh,
我可以用
不,您通常无法了解用户键入的内容。
用户可能有:
- 而是键入一个函数或包装器,它运行您的命令和其他命令,并且不能传递参数。
- 在一个高度非Bourne外壳中输入一些东西,比如Shelly的
run_"./script" ["--foo"] 。 - 单击桌面菜单而不是键入内容。
- 在一个运行在Android TV上的Java代码段中从一个不可重复的流中执行脚本。
规范行为是让调用者将
不幸的是,对于脚本,调用者的
不过还是不错的。重要的是你要用
我认为答案是否定的。好的。
如果我理解正确,您要做的就是创建一个
1 | echo"try '$user_entry -s $@' instead" |
我将讨论为什么我认为你不能低于,但首先,让我们试着理解行为。很简单,
您所描述的发生这种情况的原因是执行脚本在子shell中运行脚本。在这个子shell中,成为
转到不在您的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #/bin/bash echo"Welcome to the program!" #print out all of the arguments as given in the subshell for (( i=0;i<=$#;i++ )); do echo"Argument ${i} is: ${!i}" # bash's inderection feature, allows $0, $1, $2, ... done #endof: for (( i=0;i<=$#;i++ )) if [[ $1 !="-s" ]] ; then echo"try '$0 -s $@' instead" fi #endof: if [[ $1 !="-s" ]] echo"Working directory: $(pwd)" echo '$'"0 = $0" echo"Everything before the script name and last / :"\ '${'"0"'%/*}'" ="${0%/*} echo"Just the script name:"'${'"0"'##*/}'" ="${0##*/} while true; do echo"Hit Ctrl+C to stop this program's execution." sleep 10000 # infinite loop, with instructions on how to get out done #endof: while true |
运行
现在,如果可能的话(这将使事情更容易看到),关闭所有外壳(终端)。好的。
打开一个新的终端(我们称之为终端1)并键入
1 | Terminal1> ps |
这个
打开第二个终端,我们称之为终端2。好的。
返回终端1并键入好的。
1 | Terminal1> ps |
现在应该在输出中看到两个
可以。我们来计算一下
我们去终点站2。将目录更改为
1 | Terminal2> cd /path/to/script/ |
将脚本(在terminal2中)运行为好的。
1 | Terminal2> ./try_it.sh 1 2 3 |
我看到的是:好的。
1 2 3 4 5 6 7 8 9 10 11 12 | $ ./try_it.sh 1 2 3 Welcome to the program! Argument 0 is: ./try_it.sh Argument 1 is: 1 Argument 2 is: 2 Argument 3 is: 3 try './try_it.sh -s 1 2 3' instead Working directory: /home/me/other_dir $0 = ./try_it.sh Everything before the script name and last / : ${0%/*} = . Just the script name: ${0##*/} = try_it.sh Hit Ctrl+C to stop this program's execution. |
(不要再按"ctrl+c")注意我的
返回终端1,再次运行
1 | Terminal1> ps |
你应该看到3个
在这里,我们可以看到"给予"子壳的命令是
好的,
1 | Terminal1> ps |
只有2个
现在,尝试以下操作:好的。
1 2 3 | Terminal2> /path/to/script/try_it.sh 1 2 3 Terminal1> ps |
试试这个:好的。
1 | Terminal2> try_it.sh 1 2 3 |
你会得到一个错误。如果到可执行文件的路径没有添加到
让我们把脚本放在
1 | export PATH="$(pwd):$PATH" |
别担心,下次你关闭终端2时,这会从你的路径上消失。好的。
现在,当你还在
1 2 3 | Terminal2> try_it.sh Terminal1> ps |
"Linux的魔力"已经通过
让我们在
1 2 | Terminal2> mkdir another_directory Terminal2> cd another_directory |
让我们用相对路径来运行它。好的。
1 2 3 | Terminal2> ../try_it.sh 1 2 3 Terminal1> ps |
更疯狂的相对路径。我的
1 2 3 | Terminal2> ../../other_dir/another_directory/../try_it.sh 1 2 3 Terminal1> ps |
我们已经把脚本的路径放到了
1 2 3 | Terminal2> try_it.sh Terminal1> ps |
现在,绝对路径。这是从
1 2 3 | Terminal2> /path/to/script/try_it.sh 1 2 3 Terminal1> ps |
再一次,
我对你问题答案的看法
你问,好的。
Is there a way to find out exactly what text the user typed for the command that started the script file?
Ok.
我认为答案是否定的。如果你按照我所展示的步骤来做,我希望你能理解一点为什么你会有这样的行为。我认为,在大多数情况下,您可以找到用户键入的内容。但是,我看不出这两个命令之间有什么区别(在
1 | Terminal2> try_it.sh 1 2 3 |
和好的。
1 | Terminal2> /path/to/script/try_it.sh 1 2 3 |
也许你能想出一个方法来区分。如果是,请将其作为答案发布。好的。
注:请参阅本文和此链接(搜索"子串删除"),以获取有关
只是为了好玩好的。
让我们看看我是否真的为某人使用
1 2 3 4 5 6 7 8 9 10 11 12 | $ /path/to/script/try_it.sh -s 1 2 3 Welcome to the program! Argument 0 is: /home/dblack/other_dir/try_it.sh Argument 1 is: -s Argument 2 is: 1 Argument 3 is: 2 Argument 4 is: 3 Working directory: /home/dblack/other_dir $0 = /home/dblack/other_dir/try_it.sh Everything before the script name and last / : ${0%/*} = /home/dblack/other_dir Just the script name: ${0##*/} = try_it.sh Hit Ctrl+C to stop this program's execution. |
它奏效了。万岁!好的。好啊。