[問題] script 經 cron 執行異常但直接執行ok ?
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
03/04 04:18, 1F
系統無此兩檔QQ
→
03/04 04:18, , 2F
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
03/04 04:20, 3F
→
03/04 04:20, , 4F
03/04 04:20, 4F
→
03/04 04:21, , 5F
03/04 04:21, 5F
→
03/04 04:22, , 6F
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
03/04 04:51, 7F
→
03/04 04:53, , 8F
03/04 04:53, 8F
→
03/04 05:00, , 9F
03/04 05:00, 9F
推
03/04 11:14, , 10F
03/04 11:14, 10F
→
03/04 11:14, , 11F
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
Linux 近期熱門文章
21
56
PTT數位生活區 即時熱門文章