shell 路徑擴展對 find -name 造成的影響

shell 路徑擴展對 find -name 造成的影響

最近很多次在使用 find -name 時都會遇到一個問題。下面就是這類問題的示例:

[longyu@debian:21:20:27] ~ $ ls *.log
problem.log  system-error.log
[longyu@debian:21:20:31] ~ $ ls "*.log"
ls: cannot access *.log: No such file or directory
[longyu@debian:21:20:37] ~ $ ls '*.log'
ls: cannot access *.log: No such file or directory
[longyu@debian:21:20:41] ~ $ find ./ -name *.log
find: paths must precede expression: system-error.log
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|	opt|exec] [path...] [expression]
[longyu@debian:21:20:57] ~ $ find ./ -maxdepth 1 -name "*.log"
./system-error.log
./problem.log
[longyu@debian:21:21:13] ~ $ find ./ -maxdepth 1 -name \*\.log 
./system-error.log
./problem.log
[longyu@debian:21:21:19] ~ $ find ./ -maxdepth 1 -name \*.log
./system-error.log
./problem.log
[longyu@debian:21:21:22] ~ $ find ./ -maxdepth 1 -name '*.log'
./system-error.log
./problem.log
[longyu@debian:21:21:32] ~ $ 

從最上面 ls 命令的輸出中可以發現,當前目錄下存在兩個後綴名爲 log 的文件。緊接着的兩個失敗的 ls 命令只是用來說明 shell 的路徑擴展對程序的執行可能造成的影響。shell 在執行子程序前會進行路徑擴展,將通配符展開作爲參數傳遞給子程序,包含在雙引號中的變量也會進行變量名擴展。將通配符放在引號中是避免 shell 進行路徑擴展的一種方案,也可以通過反斜槓轉義的方式阻止 shell 進行路徑擴展。這就是 find -name 出現問題的原因,這個問題是由 shell 造成的,而非子程序的 bug

關於這點,在 find 命令的 manual 文件中有如下描述:

NON-BUGS
$ find . -name *.c -print
find: paths must precede expression
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path…] [expression]

This happens because *.c has been expanded by the shell resulting in find actually receiving
a command line like this:

  find . -name bigram.c code.c frcode.c locate.c -print

That command is of course not going to work. Instead of doing things this way, you should
enclose the pattern in quotes or escape the wildcard:
$ find . -name *.c -print

在我上面的例子中, find 執行的命令行實際爲:

find ./ -name problem.log system-error.log

這顯然不符合 find 命令的格式,通過使用引號與轉義字符便可以解決此問題,上面也給出了實例。

這個問題也會以其它的形式在我們使用其它命令時出現,這就要求我們要梳理 shell 的工作流程,至少我們必須要確保命令行是我們想要的格式,命令行很多時候都不是看上去那樣,儘管我們常常這樣認爲!

如果有一天你發現變量名擴展也會造成問題,那麼你只需要用單引號代替雙引號即可避免變量名擴展。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章