为什么第二次采购此文件的行为有所不同?

时间:2017-11-15 20:24:28

标签: bash

从这个目录结构开始:

 $ 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需要两次尝试才能找到文件?

1 个答案:

答案 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

也许您想改为get the current script's path