Bash

為什麼這個腳本在使用 crontab 自動執行時會輸出損壞的文件?

  • March 30, 2019

我有一個腳本可以掃描文件夾中的所有 .mp3 文件並創建索引。接下來它等待5s,否則它不能正常工作。最後,它會從歌曲名稱中刪除壞字元。

我使用 sudo crontab 自動執行它:

#!/bin/bash
#Creates index file.
find /var/www/html/uploads/Music/ -name '*.mp3' > /var/www/html/uploads/Music/songs.index | sleep 5s | sudo sed -i -e 's/\/var\/www\/html/\.\./g' /var/www/html/uploads/Music/songs.index

出於某種原因,當它通過 crontab 執行時,它會創建一個必須轉換為文本並返回索引才能讀取的文件。當您手動執行相同的腳本時,它可以正常工作。我錯過了什麼?

crontab 文件:

1 * * * * /home/aaeadmin/bin/midnightRun.bash

可能是因為您在管道中執行命令。

管道的每個部分同時啟動,並與同一管道的其他部分同時執行。這意味著該find命令與該命令的啟動時間完全相同sed。只有通過管道傳遞的數據,從一個命令的標準輸出到下一個命令的標準輸入,才能同步不同的命令。

另請注意,您實際上並未使用管道的管道方面。命令之間沒有數據傳遞。

你的腳本最好寫成

#!/bin/bash
#Creates index file.

find /var/www/html/uploads/Music/ -name '*.mp3' > /var/www/html/uploads/Music/songs.index

sed -i -e 's/\/var\/www\/html/\.\./g' /var/www/html/uploads/Music/songs.index

在這裡,find命令將在sed命令開始之前完成執行。我還刪除了該sudo命令,因為它顯然不需要(如果find可以寫入文件,則sed可以在沒有 的情況下讀取和修改它sudo)。

如果您發現確實需要sudo寫入songs.index,我建議您改為在屬於有權寫入目標目錄的使用者的 crontab 中執行此 cron 作業/var/www/html/uploads/Music

流水線解決方案將是

#!/bin/sh
#Creates index file.

find /var/www/html/uploads/Music/ -name '*.mp3' |    
sed -e 's,^/var/www/html,..,' >/var/www/html/uploads/Music/songs.index

這裡,直接find寫入命令,命令的結果寫入索引文件。來自into的數據(路徑名)通信使兩個程序保持同步,並在繼續之前等待產生下一行輸入(反之亦然;在嘗試輸出更多數據之前將等待處理數據)。sed``sed``find``sed``sed``find``find``sed

我還使sed命令更易於閱讀,並將正則表達式錨定到行首,並g在末尾刪除了不必要的標誌。由於它現在從find命令中讀取,因此我還刪除了該-i選項(嚴格來說,該-e選項也可以刪除)。

我改變的另一件事是#!線路。您沒有使用任何bash特定的功能,因此我們不妨使用(可能)更輕量級的 shell 來執行腳本。

如果您想將找到的文件的文件名寫入索引,並/var/www/html替換為初始文件名,..您也可以直接從find

#!/bin/sh
#Creates index file.

find /var/www/html/uploads/Music/ -type f -name '*.mp3' -exec sh -c '
   for pathname do
       printf "../%s\n" "${pathname#/var/www/html/}"
   done' sh {} + >/var/www/html/uploads/Music/songs.index

這個單一find命令將查找名稱與給定模式匹配的所有正常文件(即不是目錄等)的路徑名。對於這些路徑名的批次,呼叫一個簡短的內聯 shell 腳本。該腳本簡單地遍歷目前批次的路徑名並將它們列印出來,稍作修改。

對路徑名的修改是通過參數替換完成的${pathname#/var/www/html/}。這將從 中的值的開頭刪除字元串。然後使用的格式字元串將確保這部分被替換為./var/www/html/``$pathname``printf``../

也可以看看

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