Paano mabawi ang file na nabura sa rm -rf
Nag-run ka ng rm -rf sa maling path? Itigil agad ang pagsusulat, i-unmount ang disk, at alamin ang aktuwal na recovery options sa ext4.
Mga dapat gawin sa unang sixty seconds
Dalawang bagay ang tumutukoy kung mababawi mo ang mga file na dinelete gamit ang rm -rf, at kapwa dapat gawin bago ka magbukas ng search engine. Itigil ang pagsusulat sa filesystem na iyon. Pagkatapos, alisin ito sa paggamit sa pamamagitan ng pag-unmount dito o pag-remount dito bilang read-only.
Walang binuburang anuman ang rm. Inaalis nito ang directory entry, pagkatapos ay minamarkahan ang inode at ang mga data block ng file bilang libre. Nasa device pa rin ang mga byte. Mananatili ang mga ito roon hanggang i-assign ng block allocator ang mga block sa ibang bagay at may maisulat ang bagay na iyon sa mga ito. Sa bawat segundong naka-mount at ginagamit ang filesystem, maaaring magsulat ng isang log line ang isang daemon o mag-flush ng isang page ang database, at maaaring mapunta ang alinman sa mga pagsusulat na iyon sa mga block na gusto mong mabawi.
Kaya ang unang mga command ay dapat magpatigil ng mga pagsusulat, hindi mag-recover ng mga file.
sudo systemctl stop nginx postgresql
sudo umount /mnt/dataKung ang sagot ng umount ay umount: /mnt/data: target is busy., alamin kung ano ang nagpapanatiling bukas sa filesystem.
sudo fuser -vm /mnt/data
sudo lsof +D /mnt/dataKung hindi mo ito mapalaya, i-remount ito bilang read-only. Pinipigilan ng read-only mount ang mga bagong allocation, na siyang malaking bahagi ng kailangan mo.
sudo mount -o remount,ro /mnt/dataKung nasa root filesystem ang dineletang path, mas mahirap ito. Karaniwang mabibigo ang sudo mount -o remount,ro / gamit ang mount: /: cannot remount /dev/vda1 read-only., dahil may mga file na bukas para sa pagsusulat ang mga tumatakbong process at hindi puwersahang isinasara ng kernel ang mga ito. Sa isang VPS, ang praktikal na sagot ay ang rescue o recovery mode ng provider: nagbo-boot ito ng hiwalay na live system na nakakabit ang disk mo ngunit hindi naka-mount. Ang bawat command sa ibaba ay tatakbo laban sa isang device na walang sinusulatan.
May isang patakarang naaangkop sa buong gabay na ito. Huwag kailanman magsulat ng mga narekober na file, disk image, o bagong-install na tool sa filesystem na nire-recover mo. Mag-attach ng pangalawang volume, o ipadala ang output sa ibang machine gamit ang SSH.
Bakit halos imposibleng mabawi ang mga file gamit ang rm -rf sa ext4
Itakda muna ang tamang inaasahan bago mag-install ng anuman. Tiyakin kung anong filesystem ang ginagamit:
lsblk -fSa ext4, na default sa halos lahat ng VPS image, nasa inode ng file ang lokasyon ng data nito bilang extent tree. Ang extent ay isang record na nagsasabing ang logical block N ng file na ito ay nagsisimula sa physical block M at umaabot nang L blocks. Ang maliliit na file ay naglalaman ng hanggang apat na record sa mismong inode. Ang malalaking file ay tumuturo sa mga karagdagang block na naglalaman ng natitirang bahagi ng tree.
Kapag nawala ang huling link papunta sa isang file, tinatahak ng ext4 ang tree na iyon, ibinabalik ang bawat extent sa block allocator, at nililinis ang tree mula sa inode. Pagkatapos, minamarkahan ang inode bilang malaya at nilalagyan ng deletion time. Hindi ginagalaw ang mismong data. Nabubura lamang ang tanging record kung saan matatagpuan ang data na iyon.
Iyan ang kaibahan nito sa ext3, kung saan may sapat na natitirang impormasyon ang deleted inode para masundan ng tool gaya ng ext3grep. Maaari mo pa ring ilista ang mga deleted inode sa ext4:
sudo debugfs -R lsdel /dev/vdb1Binubuksan ng debugfs ang device bilang read-only maliban kung ipapasa mo ang -w, kaya ligtas itong gamitin sa unmounted device at walang gastos ang pagsubok. Maililista ang mga inode. Doon nagtatapos ang pag-dump ng isa, dahil nalinis na ang block map na dating nasa inode na iyon, kaya walang masusundan ang dump.
May dalawang tool na sumusubok na malampasan ito sa pamamagitan ng pagbasa sa journal. Ang journal ay isang fixed-size ring na ginagamit ng ext4 upang manatiling consistent ang metadata kapag nagkaroon ng crash, at maaari pa rin itong maglaman ng mas lumang kopya ng inode bago ito mabura. Parehong hinahanap ito ng extundelete at ext4magic. Suriin kung anong laki ang ginagamit mo:
sudo dumpe2fs -h /dev/vdb1 | grep -i journalMetadata lamang ang nasa journal at maliit ito, kaya mabilis itong napapalitan ng karaniwang write activity. Sa tumatakbong server, ilang minuto lamang ang panahong maaaring manatili ang pre-delete inode. Hindi aktibong mina-maintain ang alinmang tool, at hindi rin kasama ang mga ito sa package ng bawat distribution. Ituring ang dalawang ito bilang mga huling posibilidad, patakbuhin ang mga ito laban sa unmounted device o disk image, at huwag magulat kung wala silang maibalik.
Kung mag-ulat ang lsblk -f ng xfs, hindi rin gaganda ang sitwasyon, dahil wala ring supported undelete para sa XFS. Hindi nagbabago ang pagkakasunod-sunod ng mga option sa ibaba.
Bukas pa ba ang file sa isang tumatakbong process?
Ito ang recovery sa pahinang ito na may pinakamagandang posibilidad na magtagumpay. Ito rin ang dahilan kung bakit hindi mo dapat i-restart ang service na gumagamit ng file.
Tunay na nawawala lamang ang isang file kapag naging zero ang dalawang count: ang bilang ng directory entry na tumuturo sa inode nito, at ang bilang ng open file descriptor. Ginagawa ng rm na zero ang unang count. Kung hawak pa rin ng isang process na bukas ang file, hindi zero ang ikalawang count. Dahil dito, naka-allocate pa rin ang inode at mga block nito, at mababasa pa rin ang data.
Hanapin ang mga bukas na file na naging zero ang link count:
sudo lsof +L1Ibig sabihin ng +L1, ilista ang mga bukas na file na may link count na mas mababa sa 1. Ipinapakita ng bawat resulta ang process, file descriptor number, isang NLINK ng 0, at path na nagtatapos sa (deleted). Kunin ang PID at descriptor number, at gamitin ang /proc:
sudo ls -l /proc/1234/fdGanito ang hitsura ng isang entry: 3 -> /var/log/app/events.log (deleted). Maaabot pa rin ng link na iyon ang data. Kopyahin ito sa ibang filesystem:
sudo cp /proc/1234/fd/3 /mnt/rescue/events.logGamitin ang cp, hindi ang mv. Kapag binuksan mo ang /proc/1234/fd/3, makakakuha ka ng bagong handle sa parehong inode na nagsisimula sa offset zero. Dahil dito, makukuha mo ang buong file sa halip na ang bahaging kasunod ng kasalukuyang position ng writer.
May dalawang limitasyong dapat malaman. Hindi na maibabalik sa ganitong paraan ang isang dinelete na directory tree, dahil ang mga indibidwal na file lamang na bukas na hawak ng isang process ang nananatili. At kung kokopyahin ang database file habang nagsusulat pa ang engine, crash-consistent copy lamang ito. Kaya planuhing patakbuhin dito ang sariling recovery ng engine sa halip na ituring itong malinis na kopya. Ang mga entry na ipinapakita ng lsof na may mem sa halip na descriptor number ay memory mapped. Wala silang /proc/<pid>/fd entry na maaaring kopyahan.
May snapshot ka ba sa btrfs, ZFS, o LVM?
Kung kumukuha ng snapshot ang filesystem, nasa loob na ng isa sa mga ito ang mga dinelete na file at hindi pa nababago. Makakatulong lamang ito kung may snapshot na bago dinelete ang mga file. Walang snapshot na gagawin mo ngayon ang makakabalik sa nakaraan.
Iniimbak ng btrfs ang mga snapshot bilang mga subvolume:
sudo btrfs subvolume list /I-browse ang snapshot at kopyahin ang mga path na kailangan mo gamit ang cp -a. Mas mainam na mga indibidwal na path lamang ang kopyahin kaysa i-rollback ang buong subvolume, dahil itinatapon din ng rollback ang lahat ng naisulat mula nang gawin ang snapshot.
Inilalantad ng ZFS ang bawat snapshot bilang read-only directory:
zfs list -t snapshot
ls /tank/data/.zfs/snapshot/Nakatago ang directory na .zfs at hindi ito lalabas sa simpleng ls ng root ng dataset, pero maaari mo itong pasukin gamit ang pangalan nito. Kopyahin mula roon ang mga file. Ibinalik ng zfs rollback ang buong dataset sa dating estado at sinisira ang bawat snapshot na mas bago kaysa sa pinangalanan mo, kaya gamitin lamang ito bilang huling opsyon.
Ang LVM snapshots ay mga copy-on-write volume na may nakatakdang laki:
sudo lvs
sudo mount -o ro /dev/vg0/data-snap /mnt/snapI-mount ito bilang read-only at kopyahin mula rito ang mga kailangan mo. Suriin ang lvs bago mo ito pagkatiwalaan, dahil ini-invalidate ng kernel ang LVM snapshot kapag napuno ang inilaan nitong espasyo. Kapag nangyari na iyon, wala na ang laman nito.
Hindi backup ang isang snapshot. Nasa parehong disk o pool ito ng orihinal, kaya apektado rin ito ng bawat failure na maaaring makaapekto sa orihinal. Napakahusay nitong mag-undo ng pagkakamaling nangyari dalawang minuto ang nakalipas, at iyon mismo ang kailangan dito.
Pag-carve gamit ang PhotoRec, sa image at hindi kailanman sa live disk
Kung walang naaangkop sa mga nabanggit, ang natitira ay carving: pag-scan sa raw device para sa mga byte pattern na nagmamarka sa simula ng isang kilalang file type, at pagkatapos ay pagsusulat ng anumang sumusunod. File data lamang ang binabasa ng carving. Ang mga filename, directory structure, timestamp, at ownership ay bahagi ng filesystem metadata, at ang metadata na iyon ang winasak ng rm, kaya hindi na ito maibabalik. Makakakuha ka ng mga file na ang pangalan ay f0384512.jpg sa isang numbered output directory, at kailangan mo silang ayusin nang manu-mano.
Dalawang panuntunan ang tumutukoy kung gagana man ito.
Una, gumawa muna ng image ng device bago mo ito gamitin sa anumang iba pa. Sa Debian at Ubuntu, ang package ay gddrescue at ang binary na ini-install nito ay ddrescue.
sudo apt update && sudo apt install -y gddrescue testdisk
sudo ddrescue -n /dev/vdb1 /mnt/rescue/vdb1.img /mnt/rescue/vdb1.mapDapat nasa ibang device ang /mnt/rescue, na may libreng espasyong hindi bababa sa laki ng partition. Ipinapakita ng lsblk -b ang eksaktong laki sa bytes. Pinapahintulutan ng map file na ipagpatuloy ang naantalang pagkopya sa halip na magsimula ulit. Kapag mayroon ka nang image, maaari mong subukan sa ibang pagkakataon ang isa pang tool gamit ang eksaktong parehong bytes. Hindi mo ito magagawa kung sinulatan ng unang tool ang disk.
Ikalawa, ituro ang recovery tool sa image file.
sudo photorec /d /mnt/rescue/recup /mnt/rescue/vdb1.imgNagbubukas ang photorec ng text menu. Piliin ang partition, pagkatapos ang filesystem type, kasunod ang file signatures na hahanapin, at pagkatapos ang destination directory. Bawasan ang listahan ng signatures sa mga file type na talagang nawala bago magsimula, dahil hinahanap ng default na listahan ang lahat at bibigyan ka nito ng sampu-sampung libong fragment na kailangang salain.
May sarili ring undelete function ang testdisk, mula sa parehong package, at sinusuportahan nito ang FAT, exFAT, NTFS, at ext2 lamang. Sa ext4, ang natitira ay photorec.
Asahan na magiging sira ang mga fragmented file kapag naibalik. Ipinapalagay ng carving na magkakasunod ang mga block ng file, kaya ang file na hinati ng allocator sa magkakaibang bahagi ng disk ay maaaring mali ang pagkakabuo o tuluyang hindi matagpuan. Karaniwang maayos ang resulta ng carving para sa mga media file dahil may matitibay silang header. Mahina naman ang resulta para sa plain text, configuration, at source code, dahil walang byte signature na nagmamarka sa simula ng isang shell script.
Ang stray space: kung paano nabura ang maling path
Halos lahat ng aksidente sa rm -rf ay problema sa shell. Tumatanggap ang rm ng listahan ng mga path at binubura ang bawat isa nang paisa-isa. Hindi nito nakikita kung ano ang nilayon mo.
Ang klasikong kaso ay isang space:
rm -rf /home/deploy/app /old
rm -rf /home/deploy/app/oldDalawang argument ang unang linya. Buburahin nito ang application, saka ang /old. Kung hindi umiiral ang /old, walang ilalabas ang rm dahil pinipigilan ng -f ang error para sa nawawalang file. Ang kawalan ng output ay hindi kumpirmasyon.
Ang ikalawang anyo ay isang variable na walang quotation marks at naglalaman ng space:
dir="/srv/my app"
rm -rf $dirHinahati ng shell ang value batay sa whitespace, kaya dalawang magkahiwalay na path, /srv/my at app, ang matatanggap ng rm. Kapag isinulat bilang rm -rf "$dir", isa lamang itong path.
Ang ikatlong kaso ay isang empty variable, karaniwan dahil nabigo ang command na dapat sana ay naglagay ng value rito:
rm -rf "$TARGET"/*Kapag unset ang TARGET, nagiging rm -rf /* ang expansion. Tinatanggihan ng GNU rm ang bare form: ipinapakita ng rm -rf / ang rm: it is dangerous to operate recursively on '/' at humihinto. Walang ganitong proteksiyon ang glob form dahil pinapalitan ng shell ang /* ng listahan ng mga totoong top-level path bago pa tumakbo ang rm, at hindi kabilang dito ang /, kaya hindi gumagana ang guard.
Mga gawi para maiwasan ang susunod na insidente
- I-quote ang bawat variable na ginagamit bilang path. Isulat ang
"$dir"sa bawat pagkakataon, kabilang sa loob ng mga test at loop. - Mag-fail kapag walang laman. Pinatitigil ng
rm -rf "${TARGET:?TARGET is not set}"/*ang shell at ipinapakita ang mensahe mo bago magsimula angrm, kapag angTARGETay unset o walang laman. Ilagay angset -euo pipefailsa itaas ng anumang script na nagde-delete. - Idagdag ang
--one-file-system. Sinasabi nito sarmna laktawan ang anumang directory na nasa ibang filesystem kaysa sa argument na ibinigay mo, kaya hindi makakapasok ang recursive delete sa naka-mount na backup volume o bind mount. - Huwag mag-delete bilang root. Ang service account ay makakasira lamang ng mga file na pagmamay-ari nito. Ito ang pangunahing dahilan kung bakit dapat patakbuhin ang bawat serbisyo bilang sarili nitong unprivileged user. Kung hindi ka sigurado kung aling mga path ang maaabot ng isang account, masasagot ito ng pagbasa sa permission bits sa isang ls listing gamit ang isang command.
- I-print ang listahan bago ito gamitin. Sa isang script, buuin ang mga path,
printf '%s\n'ang mga ito, basahin ang output, at saka mag-delete sa ikalawang pass. - Panatilihing madaling ma-access ang trash command. Ibinibigay sa iyo ng
sudo apt install trash-cliangtrash-put,trash-list,trash-restoreattrash-empty. Inililipat ang mga na-delete na file sa~/.local/share/Trash, at nililinis ngtrash-empty 30ang anumang mas matanda sa thirty days.
Mukhang lohikal na susunod na hakbang ang pag-alias ng rm bilang trash-put, pero trap ito. Sinasanay ng alias ang reflex na mabibigo sa susunod na server na wala nito. Hindi rin gumagana ang mga alias sa loob ng scripts, kung saan nangyayari ang pinakamagastos na mga pagkakamali. Sadyang i-type ang trash-put sa halip.
Ang tanging recovery na palaging gumagana
Puwede lamang umasa sa lahat ng nabanggit sa itaas. Ang backup ay hindi dapat nakabatay sa suwerte.
Dalawang bagay ang nagpapatunay na maaasahan ang isang backup. Awtomatiko itong tumatakbo ayon sa schedule nang hindi mo kailangang tandaan, at kahit isang beses mo na itong na-restore. Ang repository na hindi pa kailanman ginamitan para sa restore ay paniniwala lamang, dahil lumalabas lang sa araw na kailangan mo ito ang mga problemang nagpapawalang-saysay dito, gaya ng maling path sa include list o repository password na walang nakapagtala.
Sa restic, dalawang command lang ang kailangan para sa restore.
restic -r /srv/restic-repo snapshots
restic -r /srv/restic-repo restore latest --target /mnt/rescue --include /srv/appdataI-restore ito sa isang empty directory sa halip na direktang patungan ang live path. Sa ganitong paraan, maikukumpara mo ang dalawa bago ilipat ang anumang file sa tamang lokasyon. Sinasaklaw ng Pag-set up ng restic backups sa isang VPS ang repository setup at ang systemd timer na nagpapatakbo nito.
Sa Borg:
borg list /srv/borg-repo
borg extract /srv/borg-repo::daily-2026-08-08 srv/appdataIniimbak ng Borg ang mga path sa loob ng archive nang walang leading slash. Kaya tumutugma ang srv/appdata, samantalang walang tinutugma ang /srv/appdata. Nagsusulat ang borg extract sa kasalukuyang working directory, kaya gamitin muna ang cd sa isang scratch directory.
Kung hindi ka pa nakakapili sa pagitan ng dalawang ito, saklaw ng paghahambing ng restic at Borg ang deduplication at append-only repositories. Ito ang property na pumipigil sa isang breached server na burahin ang sarili nitong backup history. Maayos gamitin ang alinman sa dalawa. Ang maling sagot ay ang hindi pagpapatakbo ng kahit alinman sa mga ito.
Ang bagong server ang pinakamurang pagkakataon para i-set up ito, bago pa magkaroon dito ng anumang ayaw mong mawala. Dito dapat gawin ang trabahong iyon: Ang unang sampung minuto sa isang bagong VPS, kasabay ng SSH at firewall setup.
Pagkatapos, maglagay ng recurring entry sa iyong calendar: bawat buwan, i-restore ang isang directory mula sa repository papunta sa /tmp at basahin ang mga file. Mas mahalaga ang simpleng habit na ito kaysa sa lahat ng tool sa page na ito.
FAQ
Maaari ko bang i-undelete ang isang file sa ext4?
Karaniwan, hindi. Kapag nawala ang huling link sa isang file, nililinis ng ext4 ang extent tree mula sa inode, kaya wala nang record sa disk kung saan nakalagay ang data. Naghahanap ang extundelete at ext4magic sa ext4 journal ng mas lumang kopya ng inode. Makakatulong lamang ito kung ilang minuto pa lang ang nakalipas nang ma-delete ang file at hindi nagkaroon ng aktibidad ang filesystem mula noon. Hindi na aktibong mina-maintain ang alinman sa mga project. Patakbuhin ang alinman sa mga ito laban sa isang unmounted device o disk image, hindi kailanman laban sa mounted filesystem. Suriin muna ang iyong ginagamit gamit ang sudo dumpe2fs -h /dev/vdb1 | grep -i journal.
Maaari ko bang mabawi ang isang deleted file na bukas pa sa isang service?
Oo, at ito ang pinakamagandang sitwasyon. Habang bukas pa ang file sa isang process, nananatiling allocated ang inode at mga data block nito, kaya readable pa ang data. Huwag i-restart ang service, dahil nakukumpleto ang delete kapag isinara ang huling descriptor. Patakbuhin ang sudo lsof +L1 upang ilista ang mga open file na may link count na 0. Itala ang PID at file descriptor number, pagkatapos ay mag-copy sa pamamagitan ng /proc gamit ang sudo cp /proc/1234/fd/3 /mnt/rescue/events.log. Isulat ang kopya sa ibang filesystem. Ang mga entry na ipinapakita ang mem sa halip na descriptor number ay memory mapped at walang /proc/<pid>/fd path na maaaring pagkunan ng kopya.
Bakit dapat kong i-image ang disk sa halip na patakbuhin dito ang recovery tool?
Dahil kailangang isulat ng bawat tool ang output nito sa isang lokasyon. Maaaring mapunta ang write sa filesystem na nire-recover mo sa mga free block na naglalaman pa ng data. I-copy muna ang partition sa ibang device gamit ang sudo ddrescue -n /dev/vdb1 /mnt/rescue/vdb1.img /mnt/rescue/vdb1.map, pagkatapos ay ituro ang photorec sa image file. Hinahayaan ka rin ng image na subukan sa ibang pagkakataon ang second tool laban sa eksaktong parehong bytes. Imposible ito kapag may naisulat na sa orihinal.
Sinisira pa rin ba ng rm -rf / ang isang Linux system?
Hindi ito ginagawa ng bare command. Tinatanggihan ito ng GNU rm at ipinapakita ang rm: it is dangerous to operate recursively on '/'. Ang mapanganib na mga anyo ay ang mga command na nabubuo sa ibang paraan. Kapag unset ang TARGET sa rm -rf "$TARGET"/*, nag-e-expand ito sa rm -rf /*. Ipinapasa ng shell sa rm ang listahan ng mga totoong top-level directory. Wala sa mga ito ang /, kaya hindi nagti-trigger ang guard. Isulat sa halip ang "${TARGET:?TARGET is not set}", at hihinto ang shell bago tumakbo ang rm.
Backup ba ang filesystem snapshot?
Hindi. Ang btrfs o ZFS snapshot ay nasa parehong pool ng data na pinoprotektahan nito. Kaya kapag nag-fail ang disk o nasira ang pool, parehong mawawala ang mga ito. May dagdag na problema ang LVM snapshot dahil fixed ang size nito. Kapag napuno ito, ini-invalidate ito ng kernel at mawawala ang laman nito. Mahusay ang snapshots para i-undo ang delete na nangyari dalawang minuto pa lang ang nakalipas. Para sa lahat ng iba pa, magpanatili ng repository sa hiwalay na hardware.