我的 中有以下行.bashrc
:
#!/usr/bin/env bash
alias see='nano --view $1'
但现在shellcheck
正在产生一个高优先级警告:
别名不能使用位置参数,而应使用函数。
合理,除了一件事:它工作得很好!这是怎么回事?
答案1
不,还有它作品因为通常$1
是空的[1]并且不被引用。由此产生的命令see foo
将是see foo
.
但是,如果您引用它,如下所示:
alias see='nano --view "$1"'
它会变成see <empty> foo
,你会打开一个新缓冲区除了foo
在nano
.
[1]
$1
扩展为无论 shell 的第一个位置参数的值是多少- 在交互式 shell 中通常什么都没有(因为交互式 shell 通常不使用位置参数来调用),但是没有什么可以阻止它被设置为任意值(例如使用set
外壳内置/ help set
) -set -- foo bar; see baz
例如foo
然后将打开baz
。(从评论中自由复制@steeldriver因为这是一个重要的注释。)
所以不要相信它总是空的。
您还可以尝试:
$ alias e='echo @$1@'
$ e foo <-- would become: echo @$1@ foo
@@ foo
| |
| +--- foo is next string
+------ $1 is empty
在引擎盖下可以这么说你会看到就像是:
execve("/bin/nano", ["nano", "--view", "foo"], 0xabc...)
对于引用的版本:
execve("/bin/nano", ["nano", "--view", "", "foo"], 0xabc...)
在主要功能中nano
int main(int argc, char *argv[])
argc
,(参数计数)将分别为 3 和 4,并且argv
,(参数向量/数组)将是方括号中的字符串。
您可以使用:
alias see='nano --view'
然后通过发出:
$ see foo
foo
将是$1
, (不是真的$1
,而是比较而言),并且该命令将扩展为:
nano --view foo
如果您需要将 nano 限制为只开放$1
,(第一个参数),您需要一个函数,因为:
see foo bar
将扩展到nano --view foo bar
然后你可以使用类似的东西:
see() {
nano --view "$1"
}
那么你会丢弃上面的任何参数$1
以及何时execve
被调用它总是:
execve("/bin/nano", ["nano", "--view", "filename"], 0xabc...)
filename
位于哪里。$1
bash
Nano看不到$1
,只有价值。 Bash 负责处理这个问题。
当使用 shell 函数时,参数被定义为位置参数,$1
, $2
, $3
, …,并且功能可以访问这些。别名不被视为函数,因此它无法访问这些参数/它们不存在。
尝试:
alias p1='echo "$# $1 END"'
p2() { echo "$# $1 END"; }
结果:
$ p1 a b c
0 END a b c
$ p2 a b c
3 a END
一般来说,Bash 手册指出:
和
没有像 csh 中那样在替换文本中使用参数的机制。如果需要参数,则应使用 shell 函数(请参阅外壳函数)。
为了shellcheck
写下来,请参阅 SC2142 的 wiki。
答案2
别名不要接受参数,它们只是按原样复制。他们似乎(有时)工作(某种程度上)。但事实并非如此。
使用外壳函数。