Rm
除少數特定文件夾外,如何遞歸刪除每個文件和文件夾?
手頭有 Busybox
ash
外殼,我希望清理/opt
文件夾。清理意味著遞歸地刪除每個文件和文件夾,除了一些需要保持不變的排除路徑。
回歸
rm
# cd /opt && echo rm -rf \ ./!(opt/etc/nginx|/opt/home|/opt/etc/config|/opt/usr/sbin|/opt/var/mlocate) -sh: syntax error: unexpected "("
回歸
find
這似乎可以完成這項工作:
# cd /opt && find ./ ! -path "./etc" ! -path "./etc/config" ! \ -path "./etc/config/*" ! -path "./etc/nginx" ! -path "./etc/nginx/*" ! \ -path "./home" ! -path "./home/*" ! -path "./usr" ! -path "./usr/sbin" ! \ -path "./usr/sbin/*" ! -path "./var" ! -path "./var/mlocate" ! \ -path "./var/mlocate/*" -exec rm -f {} \;; cd -
任何建議如何改進?使用
-delete
而不是-exec rm -f {} \
?處理rm: can't remove '.' or '..'
?如何在不遞歸的情況下刪除空目錄rm -rf
,換句話說如何整合rmdir
?注意:它是 Busybox 1.24.2,
shopt
兩者都沒有tac
。定義函式:[, [[, addgroup, adduser, ar, arping, ash, awk, base64, basename, blkid, blockdev, brctl, bunzip2, bzcat, cat, chgrp, chmod, chown, chroot, clear, cmp, cp, crond, crontab, cryptpw, cut, date, dd, delgroup, deluser, devmem, df, diff, dirname, dmesg, dos2unix, du, echo, egrep, env, expr, false, fgrep, find, free, fsync, getty, grep, gunzip, gzip, halt, head, hexdump, hostid, hostname, id, ifconfig, insmod, iostat, ip, ipaddr, ipcalc, iplink, ipneigh, iproute, iprule, iptunnel, kill, killall, klogd, less, ln, lock, logger, login, losetup, ls, lsmod, lsusb, md5sum, mkdir, mkfifo, mknod, mkswap, mktemp, more, mount, mv, nc, netmsg, netstat, nice, nslookup, ntpd, od, passwd, patch, pgrep, pidof, ping, ping6, pivot_root, poweroff, printf, ps, pwd, readlink, reboot, renice, reset, rev, rm, rmdir, rmmod, route, run-parts, sed, seq, setconsole, setserial, sh, sha1sum, sha256sum, sha512sum, sleep, sort, start-stop-daemon, stat, strings, stty, su, swapoff, swapon, switch_root, sync, sysctl, syslogd, tail, tar, tee, telnet, telnetd, test, time, top, touch, tr, traceroute, true, tty, udhcpc, umount, uname, uniq, unix2dos, unlink, unlzma, unxz, unzip, uptime, usleep, vconfig, vi, wc, wget, which, xargs, xz, xzcat, yes, zcat
嘗試:
cd /opt && find . \( \ -path ./etc/config -o \ -path ./etc/nginx -o \ -path ./home -o \ -path ./usr/sbin -o \ -path ./var/mlocate \) -prune -o \( \ -type d -print0 -o -exec rm -f {} + \) | tr '\0\n' '\n\0' | tac | tr '\0\n' '\n\0' | xargs -r0 rmdir
-prune
確保我們甚至不進入那些跳過的目錄。我們刪除其他目錄中的非目錄文件。並將目錄留待之後處理(在完成
tac
之前不會輸出任何內容find
,因為它從最後一行開始)。我們需要以相反的順序傳遞目錄列表,
rmdir
因為我們需要它在目錄本身之前刪除內容。請注意,rmdir
不會刪除非空目錄。一種通常用於
-depth
在持有它們的樹枝之前處理葉子,但我們不能使用-depth
with-prune
。出於同樣的原因,我們不能-delete
像它所暗示的那樣使用-depth
.