Shell

在“find -exec”中執行“grep | xargs”時出現空行

  • May 13, 2016

我正在嘗試通過.htaccess(包含deny from all)列出被 Apache 阻止的 Web 伺服器的所有目錄。我設法獲得了阻塞列表,.htaccess但是當我嘗試使用提取目錄路徑時dirname出現一些錯誤:

  1. 文件清單.htaccess
find . -type f -name ".htaccess"
./.htaccess
./config/.htaccess
./files/.htaccess
./plugins/webservices/.htaccess
./plugins/webservices/scripts/.htaccess
./install/mysql/.htaccess
./scripts/.htaccess
./locales/.htaccess
  1. 阻止.htaccess文件列表:
find . -type f -name ".htaccess" -exec sh -c "grep -Eli '^deny from all$' '{}'" \;
./config/.htaccess
./files/.htaccess
./plugins/webservices/scripts/.htaccess
./install/mysql/.htaccess
./scripts/.htaccess
./locales/.htaccess
  1. 錯誤來的錯誤。與 2 中的列表相同,但使用xargsanddirname獲取包含目錄:
find . -type f -name ".htaccess" -exec sh -c "grep -Eli '^deny from all$' '{}' | xargs dirname" \;
dirname: missing operand
Try dirname --help' for more information
./config
./files
dirname: missing operand
Try dirname --help' for more information
./plugins/webservices/scripts
./install/mysql
./scripts
./locales
  1. 列表 3 的調試嘗試:我們可以看到 2 個空白行,其中 2 個錯誤是:
find . -type f -name ".htaccess" -exec sh -c "grep -Eli '^deny from all$' '{}' | xargs echo" \;

./config/.htaccess
./files/.htaccess

./plugins/webservices/scripts/.htaccess
./install/mysql/.htaccess
./scripts/.htaccess
./locales/.htaccess

這些 2 個空白行顯然與.htaccess被忽略的 2 個文件匹配,因為它們不包含deny from all. 我不明白為什麼我在列表 3. 和 4. 中得到這些,但在列表 2 中沒有。

它失敗了,因為當 grep 不匹配時,您沒有將任何內容傳遞給 xargs。

例如:

  1. find獲取./.htaccess並呼叫您的-exec.
  2. 與文件中的grep任何內容都不匹配,因此它不輸出任何內容
  3. xargs在沒有任何參數的情況下啟動dirname,因此dirname認為它只是被濫用並顯示其幫助消息。

執行此操作的正確方法:

find . -type f -name .htaccess -exec grep -iq '^deny from all$' {} \; -printf '%h\n'

你有這個錯誤:

dirname: missing operand. Try dirname --help' for more information

因為dirname缺少操作數(沒有作為參數傳遞)。發生這種情況,因為grep返回了空結果。

如果您使用的是 GNU ,當輸入為空(不包含任何非空格)時xargs,您可以使用-r( ) 不執行命令。--no-run-if-empty

要使其與 BSD 一起使用xargs,您可能需要重寫命令以檢查輸入是否為空並相應地執行命令。或者只是通過抑制 stderr 來忽略錯誤,例如:

find . ... -exec sh -c "grep ... | xargs dirname 2> /dev/null || true" ';'

或者你可以使用while循環,這樣你就可以避免解析空文件或文件名中的空格問題,例如

find . -type f -name ".htaccess" -print0 | while IFS= read -r -d '' file; do

   grep -Eli '^deny from all$' "$file" | while IFS= read -r -d '' deny_file; do
     dirname "$deny_file"
   done

done

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