Linux
將最舊的文件放在 smbclient 上的 log.txt 中
我們在 1 個站點上有 94 台 PC。有一個文件夾,我們需要檢查每台 PC 上該文件夾中最舊的文件。
我可以在一個循環中執行一個包含所有 IP 的 .txt 文件,但我不知道如何檢查和獲取最舊的文件並將它們添加到 log.txt 中。我需要該日誌中該文件的名稱。
while read line; do IP=$(echo $line | cut -d ';' -f 2) NAME=$(echo $line | cut -d ';' -f 1) smbclient '\\'$IP'\C$' -W *** -U ***%*** -c "cd \*****\*****; get TheOldestFile" >> log.txt
這可以用 smbclient 做到這一點嗎?
鑑於 smbclient 命令集沒有實現完整的 shell,我最好的想法(缺少 smbounting 共享和使用本地 shell 實用程序)是“解析 ls”。
概括地說,您可以將單個 smbclient 命令替換為兩個:
smbclient ... dir
– 獲取文件列表smbclient ... get
– 獲取最舊的文件由於我沒有與您類似的環境,因此這是我要替換的“膽量”:
filename=$(smbclient '\\'$IP'\C$' -W *** -U ***%*** -c "cd \*****\*****; dir" | awk -f parse-smbclient-ls) smbclient '\\'$IP'\C$' -W *** -U ***%*** -c "cd \*****\*****; get $filename"
parse-smbclient-ls 的內容是:
BEGIN { "date +%s" | getline oldesttime } / N / { # size thu mar dd dd:dd:dd dddd if (match($0, / N +[[:digit:]]+ +[[:alpha:]]{3} [[:alpha:]]{3} +[[:digit:]]+ [[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2} [[:digit:]]{4}$/)) { timestamp=sprintf("%s %s %s %s %s", $(NF-4), $(NF-3), $(NF-2), $(NF-1), $NF) filename=substr($0, 3, RSTART-3) # trim trailing whitespace -- *** hope the real filename doesn't end in whitespace sub(/ +$/, "", filename); ("date --date='"timestamp"' +%s") | getline seconds if (seconds < oldesttime) { oldesttime=seconds oldestfile=filename } } } END { print oldestfile }
單步執行該 awk 腳本:
- 將目前最舊的日期值初始化為目前時間;希望最舊的文件至少有一秒鐘的歷史
- 如果該行匹配
/ N /
,那麼我們似乎正在查看一個正常文件(相對於目錄)- 如果該行與給定的正則表達式匹配(它會小心地只匹配 N、字節大小和時間戳,然後是行尾
$
),那麼- 提取時間戳
- 提取文件名
- 從文件名中修剪尾隨空格
- 要求 GNU date 將文件的時間戳轉換為秒
- 如果目前文件比我們擁有的文件舊,請保存時間戳和文件名
- 最後,列印最舊的文件名
請注意,這至少有兩個我知道的問題:
- 如果實際文件名以空格結尾(這是完全合法的,我相信即使在 Windows 上也是如此),那麼這個過程將以兩種方式失敗 - awk 腳本本身會修剪空格,並且命令替換也會去除尾隨空格。
- 包含(某種)特殊字元的文件被重命名;例如,當我創建一個名為 的文件時
foo$'\n'bar
,smbclientdir
命令改為顯示:FKCEWC~I
作為文件名。