[問題] script 經 cron 執行異常但直接執行ok ?

看板Linux作者 (sppmg)時間8年前 (2017/03/04 03:42), 8年前編輯推噓2(2010)
留言12則, 2人參與, 最新討論串1/1
script 功能: 可移除 qnap NAS 的 /share/tmp 中, mtime 超過 7 天的檔案。 利用 cron 定時執行。 (補充一下,相關工具如find之類全是以 ipkg 安裝之外部工具) 由於怕誤刪(rm -rf / 之類....),所以我另創帳號 sysbot_tmp_cleaner 來執行 刪除動作。/share/tmp也已經允許 sysbot_tmp_cleaner 讀寫,也實際 rmdir 過了。 設定 cron 後,的確有執行,但 find 卻找不到任何檔案。 而直接執行 script 則是可以找到檔案。 請問可能原因為何呢? script 在最下方,或是: http://pastebin.com/aPeNv2zp script 透過 cron 執行後,輸出至 log 的內容為: ------------------------ Clear time: 2017-03-04 03:15:01 sysbot_tmp_cleaner sysbot_tmp_cleaner Format is: mtime(yyyy-mm-dd) \t size(KB) \t username \t filename \n , dir name end by '/' Clear finish: 2017-03-04 03:15:01 ----------------------- 而直接執行(以admin)則是在中間的 sysbot_tmp_cleaner 前充滿檔案路徑。 另外一個奇怪的問題。為何直接以 sysbot_tmp_cleaner 執行 find /share/tmp ...... 找不到檔案,但加了/後就可以? find /share/tmp/ ...... (update: 想起來了,/share/tmp 是 soft link , 直接以 ls /share/tmp 也只是顯示 連結本身,要 ls /share/tmp/ 。大概是這原因吧!) --------- 以下 script -------------- #!/bin/sh # This script clear too old files in tmp folder . Execute by cron. # Run in every day 06:00 # echo '00 6 * * * /share/homes/admin/bin/clear_old_file.sh' > /etc/config/crontab tmp_dir="/share/tmp/" log_path="/share/system/log" log="${log_path}/clear_nas_tmp.log" lifetime_day=8 operator="sysbot_tmp_cleaner" #------------------------------------ time_start=$(date "+%F %T") # Add "/" at $tmp_dir end position, must be it or sysbot_tmp_cleaner can't get list. tmp_dir=$(echo "$tmp_dir" |sed 's/\/*$//')"/" # find and delete folders by operator # Don't use rm , it will cause error "Argument list too long". # dir first for fast remove. # Info format is: mtime(yyyy-mm-dd) \t size(KB) \t username \t filename \n , dir name end by '/' dirs_info=$(coreutils-su "$operator" -s "/bin/sh" -c " findutils-find "$tmp_dir" ! -path "$tmp_dir" -type d -mtime +${lifetime_day} ! -user admin -printf '%TY-%Tm-%Td\t%k\t%u\t%p/\n' ;whoami") # find and delete files by operator files_info=$(coreutils-su "$operator" -s "/bin/sh" -c " findutils-find "$tmp_dir" ! -path "$tmp_dir" -type f -mtime +${lifetime_day} ! -user admin -printf '%TY-%Tm-%Td\t%k\t%u\t%p\n' ;whoami") num=$(( $(wc -l <<< "$dirs_info") + $(wc -l <<< "$files_info") )) time_end=$(date "+%F %T") if [ "$num" -gt "0" ] ; then # record remove files # check if log.gz exist then unzip [ -f "${log}".gz ] && gzip -d "${log}".gz echo "Clear time: $time_start" >> "${log}" echo "$dirs_info" >> "${log}" echo "$files_info" >> "${log}" echo "Format is: mtime(yyyy-mm-dd) \t size(KB) \t username \t filename \n , dir name end by '/'" >> "${log}" echo "Clear finish: $time_end" >> "${log}" gzip "${log}" # move too old log file when > 50 MB, you can change to use logrotate log_size=$(du -ms "${log}".gz |cut -f 1 ) if [ "$log_size" -gt "50" ] ; then mv "${log}".gz ${log_path}/clear_nas_tmp.old.log.gz fi fi -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.32.188.151 ※ 文章網址: https://www.ptt.cc/bbs/Linux/M.1488570126.A.A49.html ※ 編輯: sppmg (114.32.188.151), 03/04/2017 03:44:26

03/04 04:18, , 1F
找找看/var/log/cron或/var/log/syslog之類的,應該有error
03/04 04:18, 1F
系統無此兩檔QQ

03/04 04:18, , 2F
然後你為什麼不在cron裡面指定user,要用su做?
03/04 04:18, 2F
喔,因為系統原有的 /etc/config/crontab 就沒 user 設定,可能NAS版的不支援吧。 這個是qnap的wiki: https://wiki.qnap.com/wiki/Add_items_to_crontab (ls -l => /usr/sbin/crond -> /bin/busybox 這是busybox提供的)

03/04 04:20, , 3F
findutils-find的雙引號讀起來怪怪的,$tmp_dir應該不用包?
03/04 04:20, 3F

03/04 04:20, , 4F
(不過這大概不影響)
03/04 04:20, 4F

03/04 04:21, , 5F
find的那個問題資訊有點少,亂猜會不會是這樣:
03/04 04:21, 5F

03/04 04:22, , 6F
find /share/tmp ! -path /share/tmp
03/04 04:22, 6F
find 要加"/"的理由大概是因為 /share/tmp 是 soft link,已更新。 然後我用 find /share/tmp/ ! -path /share/tmp/ 是因為find 會輸出 /share/tmp/ ,但我要去掉(不移除)。直接測是可以僅列出 其下的目錄、檔案。 ※ 編輯: sppmg (114.32.188.151), 03/04/2017 04:51:46

03/04 04:51, , 7F
NAS上的find跟一般的好像有點不同,我不會有最後的/
03/04 04:51, 7F

03/04 04:53, , 8F
喔喔,原來是因為reboot完會被清掉,而且沒有user設定
03/04 04:53, 8F

03/04 05:00, , 9F
有辦法保存嗎?我還沒測試關機後crontab能否保留 XD
03/04 05:00, 9F

03/04 11:14, , 10F
喔不是,我是說QNAP那:"Do NOT edit crontab the usual way!"
03/04 11:14, 10F

03/04 11:14, , 11F
文件上寫說不能用一般的crontab編輯方式……
03/04 11:14, 11F

03/04 11:16, , 12F
看了那你個連結才注意到上面的設定比較特殊
03/04 11:16, 12F
剛才測試了一下。google後有人有類似情況(但應非 NAS),提到環境變數問題。 所以加入環境變數測試 ---------概略 script ---------------- op_info=$(coreutils-su "$operator" -s "/bin/sh" -c ' echo op=$(whoami) echo op PATH = $PATH echo op USER = $USER') find_ver=$(coreutils-su "$operator" -s "/bin/sh" -c "findutils-find --version") echo run user = $(whoami) >> $log echo run path = $PATH >> $log echo $op_info >> $log echo "$find_ver" >> "${log}" -------------------------- 其輸出也的確是我要的: ---------概略結果------------ Clear time: 2017-03-05 00:54:01 run user = admin run path = /share/......(後面恕刪) ------ op=sysbot_tmp_cleaner op PATH = /share/......(後面恕刪) op USER = sysbot_tmp_cleaner ------ GNU find version 4.2.32 Built using GNU gnulib version 8e128ebf42e16c8631f971a68f188c30962818be Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION ---------------------------- 兩個 path 完全一樣。 find --version 也顯示能執行 find,但無論搜尋任何路徑,包括 /tmp/ /share/homes/nas_user (nas 帳號的 $HOME,同時將操作帳號改成 nas_user) 也都沒辦法。 唯一成功的只有將操作帳號改成 admin 請問各位有什麼想法呢? (如果把 findutils-find 改成基於busybox 的 ls,find 是可以執行的) ※ 編輯: sppmg (114.32.188.151), 03/05/2017 01:39:32
文章代碼(AID): #1OkSSEf9 (Linux)
文章代碼(AID): #1OkSSEf9 (Linux)