script 經 cron 執行異常但直接執行ok ? - Linux

Table of Contents

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

--

All Comments

Mason avatarMason2017-03-08
找找看/var/log/cron或/var/log/syslog之類的,應該有error
然後你為什麼不在cron裡面指定user,要用su做?
Carolina Franco avatarCarolina Franco2017-03-13
findutils-find的雙引號讀起來怪怪的,$tmp_dir應該不用包?
(不過這大概不影響)
Brianna avatarBrianna2017-03-13
find的那個問題資訊有點少,亂猜會不會是這樣:
Donna avatarDonna2017-03-14
find /share/tmp ! -path /share/tmp
Isla avatarIsla2017-03-17
NAS上的find跟一般的好像有點不同,我不會有最後的/
Steve avatarSteve2017-03-19
喔喔,原來是因為reboot完會被清掉,而且沒有user設定
Margaret avatarMargaret2017-03-21
有辦法保存嗎?我還沒測試關機後crontab能否保留 XD
Lucy avatarLucy2017-03-25
喔不是,我是說QNAP那:"Do NOT edit crontab the usual way!"
文件上寫說不能用一般的crontab編輯方式……
Rebecca avatarRebecca2017-03-26
看了那你個連結才注意到上面的設定比較特殊