Bash

find -exec 中的 if 命令

  • October 16, 2017

我只是想列出目前目錄下的所有目錄和文件,如果它們是文件或目錄,也可以使用以下命令寫入:

find -exec echo `echo {} : ;if [ -f {} ]; then echo file; else echo directory;fi` \;

我知道這是一個愚蠢的命令,我可以使用其他東西,例如-type for -type d,但我想了解為什麼那段程式碼沒有按我預期的那樣工作。它只是向所有人列印目錄。例如,雖然輸出find是:

.
./dir
./dir/file

我的程式碼的輸出是:

. : directory
./dir : directory
./dir/file : directory

和輸出

echo `echo dir/file : ;if [ -f dir/file ]; then echo file; else echo directory;fi`

dir/file : file

我正在研究Ubuntu 14.10和使用find (GNU findutils) 4.4.2

首先,您的程式碼段執行命令

echo {} : ;if [ -f {} ]; then echo file; else echo directory;fi

因為它需要它的輸出來評估命令替換。由於沒有名為{}的文件,因此會產生輸出

{} :
directory

然後使用參數, , , ,find執行該命令,因此對於每個文件,它會輸出文件名,後跟一個空格和。-exec``echo``{}``:``directory``: directory

您真正想要做的是echo {} :; …find​​. 此程式碼段必須由 生成的 shell 執行find,而不是由啟動的 shell執行find,因為它正在find從其命令行接收數據。因此,您需要指示find執行 shell:

find -exec sh -c 'echo {} : ;if [ -f {} ]; then echo file; else echo directory;fi' \;

這更好,但仍然不對。find如果您的文件名不包含任何特殊字元,它將適用於某些(不是全部)實現,但是由於您在 shell 腳本中插入文件名,因此您允許文件名執行任意 shell 命令,例如,如果您有一個名為的文件,$(rm -rf /)然後該命令rm -rf /將被執行。要將文件名傳遞給腳本,請將它們作為單獨的參數傳遞。

echo一個在冒號後列印換行符。使用echo -n(如果您的外殼支持它)或printf避免這種情況。

find -exec sh -c 'printf "%s :" "$0"; if [ -f "$0" ]; then echo file; else echo directory; fi' {} \;

您可以使用-exec … {} +對 shell 呼叫進行分組,這樣更快。

find -exec sh -c 'for x; do printf "%s :" "$x"; if [ -f "$x" ]; then echo file; else echo directory; fi; done' _ {} +

引用自:https://unix.stackexchange.com/questions/187088