以例子解釋 ‘find -exec’ 與 ‘find -execdir’ 的不同
以例子解釋 ‘find -exec’ 與 ‘find -execdir’ 的不同
find -exec
是一個很常用的指令,但有些人並不知道 find -execdir
這個指令的存在以及它們的分別,在這篇文章中,我們會探討這兩個指令的分別。
1. ‘find -exec’ 跟 ‘find -execdir’ 在不同的位置執行
find -exec
會在起始的位置執行,而 find -execdir
則會在目標存在的位置執行。
指令 | 執行位置 |
---|---|
find -exec | 起始的位置 |
find -execdir | 目標存在的位置 |
讓我們用例子解說一下吧。
-
創建以下的檔案架構。
noob@learnfromnoobs:~$ tree find-test/ find-test/ ├── dir1 │ └── myfile1 └── dir2 └── myfile2 2 directories, 2 files
我們可以用以下的指令創建上述檔案架構。
$ mkdir find-test $ mkdir find-test/dir1 $ mkdir find-test/dir2 $ touch find-test/dir1/myfile1 $ touch find-test/dir2/myfile2
-
在 find-test 下執行
find -exec
。noob@learnfromnoobs:~/find-test$ find . -name 'myfile*' -exec ls -l \; total 8 drwxrwxr-x 2 noob noob 4096 Jan 27 09:55 dir1 drwxrwxr-x 2 noob noob 4096 Jan 27 09:55 dir2 total 8 drwxrwxr-x 2 noob noob 4096 Jan 27 09:55 dir1 drwxrwxr-x 2 noob noob 4096 Jan 27 09:55 dir2
find
指令成功找到 ‘myfile1’ 和 ‘myfile2’,由於find
指令指到 2 個結果,find
指令會為每個結果在起始的位置(find-test)各自執行 1 次ls
,所以我們會看到 find-test 下的ls
結果 2 次。 -
在 find-test 下執行
find -execdir
。noob@learnfromnoobs:~/find-test$ find . -name 'myfile*' -execdir ls -l \; total 0 -rw-rw-r-- 1 noob noob 0 Jan 27 09:55 myfile1 total 0 -rw-rw-r-- 1 noob noob 0 Jan 27 09:55 myfile2
因為我們正在目標存在的位置(dir1 及 dir2)執行
ls
,所以我們會看到在 dir1 及 dir2 下的ls
結果。如果想知道更多,請參閱 find 指令的 man page。
-
如果你對上述的結果仍然抱有懷疑,你可以使用 echo 檢查一下符合 find 條件的目標。
noob@learnfromnoobs:~/find-test$ find . -name 'myfile*' -exec echo {} \; ./dir1/myfile1 ./dir2/myfile2 noob@learnfromnoobs:~/find-test$ find . -name 'myfile*' -execdir echo {} \; ./myfile1 ./myfile2
我們可以看到,對於
find -exec
指令來說,當前的位置(.)是 ~/find-test,而對於find -execdir
指令來說,當前的位置則是 ~/find-test/dir1 和 ~/find-test/dir2,亦即是目標 myfile1 和 myfile2 存在的位置。
注意
在執行指令前,我們可以使用 -ls
來檢查一下符合 find 條件的目標,確保我們真是在正確的檔案上執行指令,你永遠不會想意外地刪除了任何檔案。
noob@learnfromnoobs:~/find-test$ find . -name 'myfile*' -ls;
524517 0 -rw-rw-r-- 1 noob noob 0 Jan 27 09:55 ./dir1/myfile1
524518 0 -rw-rw-r-- 1 noob noob 0 Jan 27 09:55 ./dir2/myfile2
2. ‘find -execdir’ 不允許 ’.’ 出現在 $PATH 環境變數(Environment Variable)
根據 find 指令的 man page,
If you use this option, you must ensure that your $PATH environment variable does not reference `.’; otherwise, an attacker can run any commands they like by leaving an appropriately-named file in a directory in which you will run -execdir.
當使用 find -execdir
時,PATH 環境變數中加入 ’.’,這樣他們在當前位置執行程式時就不用在前面輸入 ‘./‘,筆者強烈不建議這樣做,如果你想知道更多,可以參這篇文章)
純粹因為實驗目的,我們可以在我們的 $PATH 環境變數中暫時加入 ’.’,看看 find -execdir
會有何回應。
-
在 $PATH 環境變數中加入 ’.’。
noob@learnfromnoobs:~/find-test$ export PATH=$PATH:. noob@learnfromnoobs:~/find-test$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:.
-
看看
find -exec
會否不滿。noob@learnfromnoobs:~/find-test$ find . -name 'myfile*' -exec ls -l \; total 8 drwxrwxr-x 2 noob noob 4096 Jan 27 09:55 dir1 drwxrwxr-x 2 noob noob 4096 Jan 27 09:55 dir2 total 8 drwxrwxr-x 2 noob noob 4096 Jan 27 09:55 dir1 drwxrwxr-x 2 noob noob 4096 Jan 27 09:55 dir2
指令順利執行了,
find -exec
不介意 ’.’ 出現在 $PATH 環境變數。 -
看看
find -execdir
會否不滿。noob@learnfromnoobs:~/find-test$ find . -name 'myfile*' -execdir ls -l \; find: The current directory is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove the current directory from your $PATH (that is, remove ".", doubled colons, or leading or trailing colons)
噢喔!很明顯,
find -execdir
不喜歡 $PATH 環境變數中存在 ’.’,指令無法執行。
總結
總結來說,find -exec
和 find -execdir
之間有 2 個分別:
find -exec
會在起始的位置執行,而find -execdir
則會在目標存在的位置執行。find -execdir
不允許 ’.’ 出現在 $PATH 環境變數。
我希望你喜歡這篇文章,並從中得到了新知識。
記得要不斷學習,have fun!