1. 程式人生 > >Linux下通過find命令進行rm文件刪除的小技巧

Linux下通過find命令進行rm文件刪除的小技巧

ase test sysconfig ger sdn tun 執行過程 fun alt

技術分享 技術分享 技術分享


我們常常會通過find命令進行批量操作。如:批量刪除舊文件、批量改動、基於時間的文件統計、基於文件大小的文件統計等。在這些操作其中,因為rm刪除操作會導致文件夾結構變化,假設要通過find結合rm的操作寫成腳本。就會遇到一些麻煩,本文通過一個樣例為大家進行介紹。


系統環境:

SUSE Linux Enterprise Server 11 或

Red Hat Enterprise Linux


問題癥狀:

客戶現場有一個自己主動化的腳本,有下面的find語句,每天執行以刪除某個文件夾下7天曾經的文件或文件夾,這些文件夾都是按時間順序生成PostgreSQL數據庫的WAL日誌及其錯誤日誌pg_log:

/bin/find /enterprisedb_backup/postgresql/ -mtime +7 -exec /bin/rm -rf ‘{}‘ \;

執行過程中。間歇性地出現下面錯誤:

[[email protected] ~]# /bin/find /enterprisedb_backup/postgresql/ -mtime +7 -exec /bin/rm -rf {} \;
/bin/find: `/enterprisedb_backup/postgresql/network-scripts‘: No such file or directory
[[email protected]
/* */ ~]# echo $? 1

顯然,以上命令返回了錯誤的結果,但客戶反映說,以上腳本執行後文件夾下7天前的數據的確備刪除了。


問題分析:

進行故障重現。在還有一臺server中通過模擬數據單獨執行find命令分析此問題。測試步驟例如以下:

  1. 模擬數據
    [[email protected] ~]# date
    Wed Jun 18 23:08:18 CST 2014
    
    [[email protected] ~]# cp -rcp /etc/sysconfig/network-scripts/ /enterprisedb_backup/postgresql/
    [[email protected]
/* */ ~]# cp -rcp /etc/init.d/iptables /enterprisedb_backup/postgresql/

## 以上通過 cp -rcp 命令使得復制到目標文件夾的數據保持包含:建立時間、用戶權根等信息,以模擬出一個舊文件及一個舊文件夾

[[email protected] ~]# ll /enterprisedb_backup/postgresql/
total 16
-rwxr-xr-x. 1 root root 9409 Oct 31  2012 iptables
drwxr-xr-x. 2 root root 4096 Jun 18  2013 network-scripts

## 以上能夠看到iptables文件是2012年建立的,network-scripts是2013年建立的,都遠遠超過了7天

[[email protected] ~]# ll /enterprisedb_backup/postgresql/*
-rwxr-xr-x. 1 root root 9409 Oct 31  2012 /enterprisedb_backup/postgresql/iptables

/enterprisedb_backup/postgresql/network-scripts:
total 212
-rw-r--r--. 1 root root   159 Jun 18  2013 ifcfg-eth0
-rw-r--r--. 1 root root   203 Jun 18  2013 ifcfg-eth1
-rw-r--r--. 1 root root   203 Jun 18  2013 ifcfg-eth2
-rw-r--r--. 1 root root   254 Jan  9  2013 ifcfg-lo
lrwxrwxrwx. 1 root root    20 Jun 18  2013 ifdown -> ../../../sbin/ifdown
-rwxr-xr-x. 1 root root   627 Jan  9  2013 ifdown-bnep
-rwxr-xr-x. 1 root root  5397 Jan  9  2013 ifdown-eth
-rwxr-xr-x. 1 root root   781 Jan  9  2013 ifdown-ippp
-rwxr-xr-x. 1 root root  4168 Jan  9  2013 ifdown-ipv6
lrwxrwxrwx. 1 root root    11 Jun 18  2013 ifdown-isdn -> ifdown-ippp
-rwxr-xr-x. 1 root root  1481 Jan  9  2013 ifdown-post
-rwxr-xr-x. 1 root root  1064 Jan  9  2013 ifdown-ppp
-rwxr-xr-x. 1 root root   835 Jan  9  2013 ifdown-routes
-rwxr-xr-x. 1 root root  1370 Jan  9  2013 ifdown-sit
-rwxr-xr-x. 1 root root  1434 Jan  9  2013 ifdown-tunnel
lrwxrwxrwx. 1 root root    18 Jun 18  2013 ifup -> ../../../sbin/ifup
-rwxr-xr-x. 1 root root 12365 Jan  9  2013 ifup-aliases
-rwxr-xr-x. 1 root root   859 Jan  9  2013 ifup-bnep
-rwxr-xr-x. 1 root root 10157 Jan  9  2013 ifup-eth
-rwxr-xr-x. 1 root root 11971 Jan  9  2013 ifup-ippp
-rwxr-xr-x. 1 root root 10401 Jan  9  2013 ifup-ipv6
lrwxrwxrwx. 1 root root     9 Jun 18  2013 ifup-isdn -> ifup-ippp
-rwxr-xr-x. 1 root root   727 Jan  9  2013 ifup-plip
-rwxr-xr-x. 1 root root   954 Jan  9  2013 ifup-plusb
-rwxr-xr-x. 1 root root  2364 Jan  9  2013 ifup-post
-rwxr-xr-x. 1 root root  4154 Jan  9  2013 ifup-ppp
-rwxr-xr-x. 1 root root  1925 Jan  9  2013 ifup-routes
-rwxr-xr-x. 1 root root  3499 Jan  9  2013 ifup-sit
-rwxr-xr-x. 1 root root  2488 Jan  9  2013 ifup-tunnel
-rwxr-xr-x. 1 root root  3770 Jan  9  2013 ifup-wireless
-rwxr-xr-x. 1 root root  4623 Jan  9  2013 init.ipv6-global
-rwxr-xr-x. 1 root root  1125 Jan  9  2013 net.hotplug
-rw-r--r--. 1 root root 13079 Jan  9  2013 network-functions
-rw-r--r--. 1 root root 29853 Jan  9  2013 network-functions-ipv6

## 以上能夠看到network-script不是一個空的文件夾,其中還有文件,並且文件也都已經是7天前建立的了

  • 測試單獨模擬運行腳本中的find + rm指令

    [[email protected] ~]# /bin/find /enterprisedb_backup/postgresql/ -mtime +7 -exec /bin/rm -rf {} \;
    /bin/find: `/enterprisedb_backup/postgresql/network-scripts‘: No such file or directory
    [[email protected] ~]# echo $?
    1
    [[email protected] ~]# ls /enterprisedb_backup/postgresql/
    [[email protected] ~]#
    
    能夠看到find操作的確返回了錯誤的結果,但查看數據備份文件夾發現,iptables文件及network-scripts文件夾已經正確刪除

  • 因為數據已經正確刪除,因此我們開始懷疑是由network-scripts文件夾刪除後。find繼續嘗試刪除此文件夾下其他文件。導致出不“No such file or directory”的錯誤。因此須要於進一步證實此猜想。又一次運行以上“第1步”中的數據環境模擬。並運行下面操作,主要是將rm轉換成ls以展現總體運行過程:
    [[email protected] ~]# cp -rcp /etc/sysconfig/network-scripts/ /enterprisedb_backup/postgresql/
    [[email protected] ~]# cp -rcp /etc/init.d/iptables /enterprisedb_backup/postgresql/
    [[email protected] ~]# /bin/find /enterprisedb_backup/postgresql/ -mtime +7 -exec /bin/ls {} \;
    ifcfg-eth0  ifcfg-lo	 ifdown-eth   ifdown-isdn  ifdown-routes  ifup		ifup-eth   ifup-isdn   ifup-post    ifup-sit	   init.ipv6-global   network-functions-ipv6
    ifcfg-eth1  ifdown	 ifdown-ippp  ifdown-post  ifdown-sit	  ifup-aliases	ifup-ippp  ifup-plip   ifup-ppp     ifup-tunnel    net.hotplug
    ifcfg-eth2  ifdown-bnep  ifdown-ipv6  ifdown-ppp   ifdown-tunnel  ifup-bnep	ifup-ipv6  ifup-plusb  ifup-routes  ifup-wireless  network-functions
    /enterprisedb_backup/postgresql/network-scripts/ifup-plusb
    /enterprisedb_backup/postgresql/network-scripts/ifup-sit
    /enterprisedb_backup/postgresql/network-scripts/ifdown-post
    /enterprisedb_backup/postgresql/network-scripts/ifcfg-lo
    /enterprisedb_backup/postgresql/network-scripts/network-functions
    /enterprisedb_backup/postgresql/network-scripts/ifup-bnep
    /enterprisedb_backup/postgresql/network-scripts/ifup-ippp
    /enterprisedb_backup/postgresql/network-scripts/ifdown-sit
    /enterprisedb_backup/postgresql/network-scripts/ifdown-tunnel
    /enterprisedb_backup/postgresql/network-scripts/ifup-plip
    /enterprisedb_backup/postgresql/network-scripts/ifup-eth
    /enterprisedb_backup/postgresql/network-scripts/ifdown-ipv6
    /enterprisedb_backup/postgresql/network-scripts/ifdown-ippp
    /enterprisedb_backup/postgresql/network-scripts/ifup-aliases
    /enterprisedb_backup/postgresql/network-scripts/network-functions-ipv6
    /enterprisedb_backup/postgresql/network-scripts/ifup-ipv6
    /enterprisedb_backup/postgresql/network-scripts/ifup-post
    /enterprisedb_backup/postgresql/network-scripts/ifcfg-eth2
    /enterprisedb_backup/postgresql/network-scripts/ifcfg-eth1
    /enterprisedb_backup/postgresql/network-scripts/ifdown-ppp
    /enterprisedb_backup/postgresql/network-scripts/ifup-isdn
    /enterprisedb_backup/postgresql/network-scripts/ifcfg-eth0
    /enterprisedb_backup/postgresql/network-scripts/ifdown
    /enterprisedb_backup/postgresql/network-scripts/ifup-wireless
    /enterprisedb_backup/postgresql/network-scripts/ifup-ppp
    /enterprisedb_backup/postgresql/network-scripts/ifdown-eth
    /enterprisedb_backup/postgresql/network-scripts/init.ipv6-global
    /enterprisedb_backup/postgresql/network-scripts/ifdown-isdn
    /enterprisedb_backup/postgresql/network-scripts/ifup-tunnel
    /enterprisedb_backup/postgresql/network-scripts/ifdown-routes
    /enterprisedb_backup/postgresql/network-scripts/ifdown-bnep
    /enterprisedb_backup/postgresql/network-scripts/net.hotplug
    /enterprisedb_backup/postgresql/network-scripts/ifup
    /enterprisedb_backup/postgresql/network-scripts/ifup-routes
    /enterprisedb_backup/postgresql/iptables
    通過以上操作我們能夠看到。find命令不單查詢了/enterprisedb_backup/postgresql/文件夾,而且遍歷了全部子文件夾。因此支持了我們的判斷

  • 綜上所述基本定位問題所在

  • 分析圖解:

    技術分享技術分享技術分享技術分享技術分享這個圖不知讓咋畫技術分享技術分享技術分享技術分享技術分享


    解決方式:

    1. 整理思路後,能夠確認,假設find僅僅找出所需操作文件夾的第1層文件及文件夾就可以解決此問題
    2. 通過偉大的 man 命令我們得到下面信息
      -maxdepth levels
          Descend at most levels (a non-negative integer) levels of directories below the command line arguments. -maxdepth 0 means only apply the tests and actions to the command line arguments. 

    3. 測試操作確認改動為:
      [[email protected] ~]# /bin/find /enterprisedb_backup/postgresql/ -mtime +7 -maxdepth 1 -exec /bin/rm -rf {} \;
      /bin/find: warning: you have specified the -maxdepth option after a non-option argument -mtime, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it).  Please specify options before other arguments.
      
      這裏意思是說:-mtime找到的信息可能會操過-maxdepth的範圍。在find操作中建議-maxdepth放在全部其它參數的前面

    解決結果【完畢】

    Linux下通過find命令進行rm文件刪除的小技巧