Bash 为什么第二次查找此文件的行为会有所不同?

Bash 为什么第二次查找此文件的行为会有所不同?,bash,Bash,从这个目录结构开始: $ tree . ├── 1 │   └── 2 │   └── foo.jar └── a └── b └── c └── setAlias 目标是提供setAlias的内容,这样我就可以获取该文件的源代码,它将创建一个运行java-jar/absolute/path/to/foo.jar的别名 以下是我目前掌握的情况: FOO="java -jar $(realpath $(dirname $_)/../../

从这个目录结构开始:

 $ 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中获取源代码,则一切正常。但是如果我从根目录设置它,我必须在解析绝对路径之前运行它两次:

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

这是一件非常奇怪的事情,但很容易解释。下面是ManBash在特殊参数下的摘录

展开后,$\u[..]展开到上一个命令的最后一个参数。[……]

换句话说,它指的是最近执行的命令的最后一个参数:

$ echo foo bar baz
foo bar baz

$ echo $_
baz
在您的情况下,您运行了一些未在帖子中显示的任意命令,后跟源代码两次:

换句话说,只有在前面有一个命令,该命令使用您所需的$作为其最后一个参数时,源代码才会工作。这可以是任何东西:

$ 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

也许您想改为?

bash手册页包含以下行已经很长时间了:对于几乎所有用途,别名都被shell函数取代。注意,不要使用别名。别说了,我一定会铭记在心的。我不知道为什么我不想只导出一个函数,我脑子里想$\u会给我source的参数,我可以从中构造我需要的路径。它似乎在大多数情况下都有效,因为之前的命令通常是cd a/b/c。您链接到的帖子显示了如何获取我想要的内容。谢谢
$ 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