从这个目录结构开始:
$ tree
.
├── 1
│ └── 2
│ └── foo.jar
└── a
└── b
└── c
└── setAlias
目标是提出setAlias的内容,以便我可以获取该文件,并创建一个运行java -jar /absolute/path/to/foo.jar
的别名
这是我到目前为止所拥有的:
FOO="java -jar $(realpath $(dirname $_)/../../../1/2/foo.jar)"
echo "Setting Alias:"
echo " foo -> $FOO"
alias foo='$FOO'
如果我直接从自己的setAlias
获取,那么一切正常。但是如果我从根目录设置它,我必须在解决absoulute路径之前运行它两次:
$ source a/b/c/setAlias
realpath: ./../../../1/2/foo.jar: No such file or directory
Setting Alias:
foo -> java -jar
$ source a/b/c/setAlias
Setting Alias:
foo -> java -jar /home/MatrixManAtYrService/1/2/foo.jar
如果我从./a/b/c
执行此操作,则首次尝试解析路径。
这里发生了什么?为什么realpath需要两次尝试才能找到文件?
答案 0 :(得分:1)
这是一件非常奇怪的事情,但很容易解释。以下是特殊参数
下man bash
的摘录
扩展后,
$_
[..]扩展为上一个命令的最后一个参数。 [...]
换句话说,它指的是最近执行的命令的最后一个参数:
$ echo foo bar baz
foo bar baz
$ echo $_
baz
在您的情况下,您运行了一些未在帖子中显示的任意命令,然后是source
两次:
$ true foobar # $_ now becomes "foobar"
$ source a/b/c/setAlias # fails because $_ is "foobar", sets $_ to a/b/c/setAlias
$ source a/b/c/setAlias # works because $_ is now "a/b/c/setAlias"
换句话说,只有在使用source
所需的值作为最后一个参数的命令之前,$_
才有效。这可能是任何事情:
$ wc -l a/b/c/setAlias # also sets $_ to a/b/c/setAlias
4
$ source a/b/c/setAlias # Works, because $_ is set to the expected value