我正在尝试为我的查找命令着色,所以我已将此别名函数添加到我的 .bashrc 中。
# liberate your find
function find
{
command find $@ -exec ls --color=auto -d {} \;
}
但是使用这段代码有意想不到的行为。它删除了我的报价。
GNU bash,版本 4.4.23(1)-release (x86_64-pc-linux-gnu)
使用我的函数:
find ./ -name '*.pl' -or -name '*.pm'
结果:
./lib/cover.pm
./lib/db.pm
使用相同的查找功能,但内置:
command find ./ -name '*.pl' -or -name '*.pm'
结果:
./auth.pl
./index.pl
./title.pl
./lib/cover.pm
./lib/db.pm
./fs2db.pl
所以第二个变体没有吃掉我的引语并且正常工作。
为了重现问题,我创建了所有文件,如问题中较长的结果所示。
当我将函数(*) 定义为
function find
{
command find $@ -exec ls --color=auto -d {} \;
}
并执行
find ./ -name '*.pl' -or -name '*.pm'
我收到一条错误消息
find: paths must precede expression: fs2db.pl
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
因为 *.pl
被 shell 扩展为 auth.pl fs2db.pl index.pl title.pl
。
我不得不将函数更改为
function find
{
command find "$@" -exec ls --color=auto -d {} \;
}
重现您的问题。 (也许这取决于 shell。我用 bash 4.4.19(3)-release 测试过)
在 set -x
之后,您可以看到 shell 在执行您的函数时做了什么:
$ find ./ -name '*.pl' -or -name '*.pm'
+ find ./ -name '*.pl' -or -name '*.pm'
+ command find ./ -name '*.pl' -or -name '*.pm' -exec ls --color=auto -d '{}' ';'
+ find ./ -name '*.pl' -or -name '*.pm' -exec ls --color=auto -d '{}' ';'
./lib/cover.pm
./lib/db.pm
执行你的函数和直接执行find
命令的区别在于你的函数附加了一个-exec
Action 和隐含的-a
(AND) 运算符。如果没有明确的操作,find
会打印所有匹配的结果。
您会看到运算符优先级 -a
(AND) 高于 -o
(=-or
, OR) 的结果
你可以比较这3个命令的输出
command find ./ -name '*.pl' -or -name '*.pm'
command find ./ -name '*.pl' -or -name '*.pm' -print
command find ./ \( -name '*.pl' -or -name '*.pm' \) -print
参见 http://man7.org/linux/man-pages/man1/find.1.html#NON-BUGS
你可以调用你的函数
find ./ \( -name '*.pl' -or -name '*.pm' \)
避免问题。
(*) 这个函数定义是从问题中复制过来的。
您应该改用可移植的 POSIX 样式 find() { ... }
,除非对 Korn shell 样式 function find { ... }
有特定要求。