如何統計整個系統中所有的 python 和 shell 腳本?
答案1
在沒有更具體的目標的情況下,無論您如何執行,這都將是近似的,因為關於什麼構成 shell 腳本和什麼構成 Python 腳本存在模糊性。這並不會讓問題變得太不明確,只要你想要一個近似值。你可以獲得一個很好的近似值。
有鑑於此,我建議使用此命令列出 shell 和 Python 腳本:
find . -type f -executable -exec file {} + | grep -Ei '(python|shell) script,'
如果輸出看起來符合您的需求,您可以再次執行它,修改為計算結果數:
find . -type f -executable -exec file {} + | grep -Ei '(python|shell) script,' | wc -l
您可能會收到一些“權限被拒絕”錯誤。沒關係。我不建議嘗試隱藏這些錯誤訊息,因為您應該閱讀或至少掃描它們,看看您是否無法存取您感興趣的任何文件或位置。如果您確實願意,可以find
以 root 身分執行該命令。sudo
-type f
使其僅查找常規文件。通常最好使用-xtype f
包含解析為常規文件的符號鏈接,但在這種情況下,這會導致計數過多。-executable
使其僅查找正在執行的使用者可執行的檔案find
。查看非可執行檔以查看它們是否是 shell 或 Python 腳本將使命令花費相當長的時間。透過這種方式,您也可能會得到更多誤報,因為不可執行的檔案可能是「庫」而不是腳本,即它們可能由 shell 命令組成,並且旨在與 shell 腳本一起獲取.
或source
進入shell 腳本,或者它們可能是可與 Python 程式一起匯入import
或from
匯入到 Python 程式中的 Python 模組。 (您可能認為這不會發生,因為此類文件通常沒有舍邦,但find
查找的不僅僅是 shebang-executable
。如果你願意等待當您的命令嘗試開啟並讀取系統上每個常規檔案的開頭。-exec ... +
...
使用找到的檔案作為命令列參數來運行命令。它根據需要多次運行命令來處理所有檔案。通常這只是一次;對於整個系統上的所有可執行文件,它可能會不止一次,但比每個文件運行一次要少得多(就像-exec ... \;
會做的那樣)。即使在相同數量的文件上,運行命令次數較少往往比運行命令次數較多要快得多,因為相關開銷較低。- 該
file
命令查看文件的開頭並通常很好地猜測它是什麼類型的文件。它以兩列格式輸出,路徑或檔案名稱位於左側,以及內容摘要種類文件的它似乎位於右側。 - 此
grep
命令過濾其輸入並僅輸出不區分大小寫 (-i
) 與擴展正規表示式(-E
)(python|shell) script,
。這些是包含文字python script,
、shell script,
或其任何大小寫變體的行。文件find
標識為這些類型的腳本將顯示這一點。 wc -l
出現在上面顯示的兩個命令中的第二個中,用於計算行數。
如圖所示,該技術完全不適合許多涉及辨別一個人擁有什麼類型的文件的任務。原因是文件可能包含python script,
其名稱中的文字以及名稱中的換行符,這將導致輸出不是file
每行一個。解釋這些事情通常很重要,甚至常常至關重要,而且是可以做到的。然而,在這種情況下,您只是進行估計(由於問題本身的模糊性質),而且您似乎沒有直接根據結果重命名、修改、刪除甚至創建任何內容,所以我我認為不值得為此擔心。如果您最終對此進行迭代並更嚴格地定義問題,那麼解決這個問題可能是值得的。
請注意,在一個主要情況下,您可能希望將不可執行的檔案視為腳本:如果您有許多從 Windows 等系統引入的 Python 腳本,而這些腳本未標記為可執行。在這種情況下,您可以搜尋.py
文件,但請注意其中許多文件可能是 Python 模組而不是 Python 腳本。如果遵循了將 hashbang 放在腳本頂部的良好 Python 實踐(這即使在 Windows 中也很有用,因為py.exe
並pyw.exe
識別它們,儘管不幸的是並不總是這樣做),那麼一種只查找hashbang 但忽略if 的技術可執行檔可能更適合您的需求。
還有一種次要但重要的情況,您可能希望將不可執行檔視為任何類型的腳本,或者更準確地說,您可能希望以不同的方式測試可執行性。如果您安裝了驅動器noexec
,則其上的任何檔案都不會通過find
測試-executable
。請注意,這與以find
無權執行某些文件的用戶身份運行是不同的問題
這個問題,正如你所提出的,很不尋常——通常人們會想要找到特定語言或密切相關的一組語言的文字。但為了未來讀者的利益,請注意,透過對上述指令進行輕微修改,也可以在單一(可能很大)目錄中找到所有(例如)shell 腳本。 (這同樣適用於中所提出的技術WinEunuuchs2Unix 的回答——這也很有用。
例如,要尋找目前目錄中的所有 shell 腳本:
find . -type f -executable -exec file {} + | grep -Fi 'shell script,'
答案2
快速概覽
這是有關如何操作的指南。
$ for f in * ; do file "$f" ; done
aptfielout: ASCII text, with very long lines
aptfilein: ASCII text, with very long lines
aptfileout: ASCII text
aptfileparse.sh: Bourne-Again shell script, ASCII text executable, with very long lines
aptfileparse.sh~: ASCII text, with very long lines
calc.py: Python script, UTF-8 Unicode text executable
catall.sh: Bourne-Again shell script, ASCII text executable
刪除所有未註明「Bourne-Again shell 腳本」或「Python 腳本」的檔案。新增到 POSIX shell 腳本清單:
$ file /bin/zgrep
/bin/zgrep: POSIX shell script, ASCII text executable
完整的答案
/$ time find * -type f -print0 2>/dev/null | xargs -0 -P 8 file | \
sed 's/.*: //g' | sed 's/^ *//g' | \
grep -Eio 'shell script,|Python script,' | sort | uniq -c
19151 Python script,
127 python script,
18420 shell script,
real 16m14.939s
user 54m7.355s
sys 2m33.238s
從根 ( /
)開始find
,所有檔案和管道都xargs
以零位元組終止名稱傳送到命令。
此xargs
命令並行運行,最大化所有 8 個 CPU 以加快處理速度。每個並行進程都會呼叫該file
指令來取得檔案的描述,如上一節所示。
該grep
指令選擇 shell 腳本和 python 腳本。
這個sort
指令將 shell 腳本和 python 腳本一起排序。
此uniq
指令計算每個組別的出現次數。
有趣的事實
您確實可以同時對運行所有 8 個 CPU(在我的例子中)的系統進行徵稅:
Linux 的美妙之處在於,其他工作(例如製作螢幕錄影機.gif
和在第三台顯示器(大螢幕電視)上運行的影片)繼續正常運作。 Linux 不會讓該xargs file
指令讓系統陷入困境。