我正在尝试创建一个简单的别名,该别名使用带有完整路径的参数
在命令行上,我可以输入command "$(pwd)/my_file"
.有用。所以我尝试通过以下方式创建别名:
alias command='command "$(pwd)/$1"'
但这个别名不起作用。 CLI 解释为好像$(pwd)
和my_file
是分开的参数...我尝试使用该eval
命令将我的命令变成单个命令
alias command="eval 'command' '$(pwd)/$1'"
然而,它一直在等待输入参数,而不是接受我的初始参数......
如果您想尝试我的意思,请替换command
(evince
流行的 PDF 查看器)和my_file
任何 PDF 文件。所以我的别名是
alias evince="evince $(pwd)/$1"
就我而言,$(pwd)
是/home/tapyu/Downloads/
,并且my_file
是recap.pdf
。我知道 evince 将其视为一个单独的参数,因为它会弹出两个窗口:第一个窗口recap.pdf
正确打开。第二个是一个带有警告的空窗口"Error opening file, /home/tapyu/Downloads/ is a directory."
先感谢您。
PS:我知道这个“问题”是没有意义的。我的问题不是“如何给出命令的完整路径”,我的问题是“如何处理别名中的输入参数以解决这种情况”。因此,不想使用替代方案来提供完整路径,我想知道为什么我的别名不起作用。
答案1
第一个问题是别名不带参数。如果您需要将参数传递给别名,这意味着你应该使用一个函数。如果运行以下命令,您可以看到会发生什么set -x
:
$ alias evince="evince $(pwd)/$1"
$ set -x
$ evince a.pdf
+ evince /home/terdon/foo/ a.pdf
正如您所看到的,命令evince a.pdf
变为evince /home/terdon/foo/ a.pdf
(我在目录中运行它/home/terdon/foo/
)。那么这是怎么回事呢?看看你的别名实际上是什么:
$ type evince
evince is aliased to `evince /home/terdon/foo/'
set -x
如果您运行然后定义别名,您甚至可以看到这种情况发生:
$ alias evince="evince $(pwd)/$1"
++ pwd
+ alias 'evince=evince /home/terdon/foo/'
当您定义别名时,$1
没有任何值,并且pwd
在设置别名之前运行,因此您实际上别名为evince /home/terdon/foo/
.然后,当你运行时evince a.pdf
,它实际上运行了,evince /home/terdon/foo/ a.pdf
这就是你得到两个窗口的原因。
一个函数看起来像这样:
evince(){
command evince "$(pwd)"/"$1"
}
注意 : 的使用command
是为了确保evince
函数内部会调用命令 evince
而不是函数本身递归。另请注意,这是一个毫无意义的示例,因为evince foo
它本身与 完全相同evince $(pwd)foo
。如果文件位于当前目录中,则不需要该文件的完整路径。
答案2
别名不接受参数,它们只是简单的文本替换。 (与 shell 中的其他所有内容不同。)$1
将有定义或使用别名的上下文的第一个位置参数。无论如何,交互式 shell 中可能是空的。
到底发生什么还取决于您在定义别名时使用的引号......
如果你有
alias evince="evince $(pwd)/$1"
扩展$(pwd)
并将$1
立即扩展(因为它们在双引号内)。$(pwd)
将扩展到此时的工作目录,并且$1
无论当前 shell 的第一个位置参数(命令行参数)是什么,可能什么都没有。所以你会得到类似的东西:
alias evince="evince /some/path/"
之后,evince foo.pdf
跑步
evince /some/path/ foo.pdf
确实有两个参数evince
。
另一方面,如果你有
alias evince='evince $(pwd)/$1'
扩展做不是就在那里展开,但仅在使用别名时才进行。运行evince foo.pdf
将扩展到
evince $(pwd)/$1 foo.pdf
$(pwd)
工作目录在哪里现在,并且$1
仍然是 shell 的第一个位置参数,可能为空。你再次得到
evince /current/path foo.pdf
(加上未引用扩展的任何可能的问题)
使用函数代替。
看: