Isichazi sefayile kwiLinux enemizekelo

Kanye, kudliwano-ndlebe, ndabuzwa ukuba ubuya kwenza ntoni xa ufumana inkonzo eyaphukileyo ngenxa yokuba idiski iphelelwe yindawo?

Ewe, ndaphendula ndathi ndiza kubona ukuba le ndawo yenza ntoni kwaye, ukuba kunokwenzeka, ndiza kuyicoca indawo.
Emva koko udliwano-ndlebe wabuza, kuthekani ukuba akukho ndawo yamahhala kwisahlulo, kodwa awuboni iifayile eziza kuthatha yonke indawo?

Kule nto, ndathi unokuhlala ujonga izichazi zefayile ezivulekileyo, umzekelo, kunye nomyalelo we-lsof kwaye uqonde ukuba yeyiphi isicelo esithathe yonke indawo ekhoyo, kwaye ke unokwenza ngokweemeko, kuxhomekeke ekubeni idatha iyafuneka. .

Udliwano-ndlebe wandiphazamisa kwigama lokugqibela, wongeza kumbuzo wakhe: "Masithi asiyidingi idatha, yi-log ye-debug nje, kodwa isicelo siphantsi ngenxa yokuba ayikwazi ukubhala i-debug"?

"Kulungile," ndaphendula, "singacima ukulungisa ingxaki kwisicelo kwaye siyiqale kwakhona."
Udliwano-ndlebe wachasa: "Hayi, asinakuphinda siqalise isicelo, sisenedatha ebalulekileyo kwimemori, kwaye abathengi ababalulekileyo baqhagamshelwe kwinkonzo ngokwayo, esingenako ukunyanzela ukuba siyidibanise."

"Kulungile," ndatsho, "ukuba asikwazi ukuqalisa kwakhona isicelo kwaye asikhathali ngedatha, ngoko sinokuyicima le fayile evulekileyo ngokuchaza ifayile, nokuba asiyiboni kwi-ls. umyalelo kwisixokelelwano sefayile.

Lowo wayethetha naye wanelisekile, kodwa andizange ndivume.

Ndiye ndacinga, kutheni umntu ovavanya ulwazi lwam engombi nzulu? Kodwa kuthekani ukuba idatha ibalulekile emva kwayo yonke loo nto? Kuthekani ukuba asikwazi ukuqalisa kwakhona inkqubo, kwaye kwangaxeshanye le nkqubo ibhalela inkqubo yefayile kwisahlulelo esingenandawo yasimahla? Kuthekani ukuba asikwazi ukulahlekelwa kuphela idatha esele ibhaliwe, kodwa kunye nedatha ukuba le nkqubo ibhala okanye izama ukuyibhala?

Tuzik

Ekuqaleni komsebenzi wam, ndandizama ukwenza isicelo esincinci esifunekayo ukugcina ulwazi malunga nabasebenzisi. Kwaye ke ndacinga, ndingafanisa njani umsebenzisi nedatha yakhe. Ngokomzekelo, ndino-Ivanov Ivan Ivanovich, kwaye unedatha ethile, kodwa indlela yokwenza ubuhlobo nabo? Ndiyakwazi ukukhomba ngokuthe ngqo ukuba inja egama lingu "Tuzik" ingowalo Ivan. Kodwa kuthekani ukuba utshintsha igama lakhe kwaye endaweni ka-Ivan uba, umzekelo, u-Olya? Emva koko kuya kuvela ukuba u-Olya Ivanovna Ivanova wethu akayi kuba nenja, kwaye iTuzik yethu iya kuba ye-Ivan engekho. I-database incede ukuxazulula le ngxaki, eyanika umsebenzisi ngamnye isazisi esikhethekileyo (ID), kwaye i-Tuzik yam ibotshelelwe kule ID, leyo, ngokwenene, yayiyinombolo ye-serial nje. Ngaloo ndlela, umnini we-tuzik wayenenombolo ye-ID yesi-2, kwaye ngexesha elithile u-Ivan wayephantsi kwesi sazisi, kwaye u-Olya waba phantsi kwe-ID efanayo. Ingxaki yoluntu nemfuyo yaconjululwa ngokoqobo.

Isichazi sefayile

Ingxaki yefayile kunye neprogram esebenza nale fayile imalunga nokufana nenja yethu kunye nomntu. Masithi ndivule ifayile ebizwa ngokuba yivan.txt kwaye ndaqala ukubhala igama elithi tuzik kuyo, kodwa ndakwazi ukubhala kuphela ileta yokuqala "t" kwifayile, kwaye le fayile yaqanjwa ngokutsha ngumntu, umzekelo, ku-olya.txt. Kodwa ifayile iyafana kwaye ndisafuna ukubhala i-ace kuyo. Ngalo lonke ixesha uvula ifayile ngomnxeba wenkqubo evulekileyo kulo naluphi na ulwimi lwenkqubo, ndifumana isazisi esisodwa esindikhomba kwifayile, le ID yinkcazo yefayile. Kwaye akukhathaliseki nokuba ngubani olandela le fayile, ingacinywa, ithiywe ngokutsha, inokutshintsha umnikazi wayo okanye ithathe amalungelo okufunda nokubhala, ndiseza kuba nako ukufikelela kuyo, kuba ngexesha lokuvula ifayile ndandinamalungelo okuyifunda kunye / okanye ukuyibhala kwaye ndakwazi ukuqalisa ukusebenza nayo, oku kuthetha ukuba kufuneka ndiqhubeke ndenza njalo.

Kwi-Linux, ilayibrari ye-libc ivula iifayile ezi-3 zokuchaza kwisicelo ngasinye esisebenzayo (inkqubo), enamanani 0,1,2. Ulwazi oluninzi ungalufumana kwiilinki indoda stdio ΠΈ indoda stdout

  • Inkcazo yefayile 0 ibizwa ngokuba yi-STDIN kwaye inxulunyaniswa negalelo lesicelo.
  • Isichazi sefayile 1 sibizwa ngokuba yi-STDOUT kwaye isetyenziswa zimveliso zemveliso ezifana nemiyalelo yoshicilelo.
  • Isichazi sefayile 2 sinegama elithi STDERR kwaye isetyenziswa zizicelo ukukhupha imiyalezo yemposiso.

Ukuba kwiprogram yakho uvula nayiphi na ifayile yokufunda okanye yokubhala, ngoko ke uya kufumana i-ID yokuqala yasimahla kwaye oku kuya kuba yinombolo yesi-3.

Ungalubona uluhlu lwezichazi zefayile kuyo nayiphi na inkqubo ukuba uyayazi iPID yayo.

Umzekelo, masivule ikhonsoli nge-bash kwaye sibone i-PID yenkqubo yethu

[user@localhost ]$ echo $$
15771

Kwi-console yesibini, baleka

[user@localhost ]$ ls -lah /proc/15771/fd/
total 0
dr-x------ 2 user user  0 Oct  7 15:42 .
dr-xr-xr-x 9 user user  0 Oct  7 15:42 ..
lrwx------ 1 user user 64 Oct  7 15:42 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:42 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:42 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:42 255 -> /dev/pts/21

Ungayihoyi ngokukhuselekileyo inkcazo yefayile enenombolo ye-255 ngaphakathi kwesakhelo seli nqaku, yavulelwa iimfuno zakho nge-bash ngokwayo, kwaye kungekhona ngelayibrari edibeneyo.

Ngoku zonke iifayile ezi-3 zokuchaza zinxulunyaniswa nesixhobo se-pseudo-terminal /dev/pts, kodwa sisenako ukuzisebenzisa, umzekelo, sebenzisa i console yesibini

[user@localhost ]$ echo "hello world" > /proc/15771/fd/0

Kwaye kwi-console yokuqala siza kubona

[user@localhost ]$ hello world

Ukwalathisa kwakhona kunye noMbhobho

Uyakwazi ukugqithisa ngokulula ezi 3 iifayile ezichazayo kuyo nayiphi na inkqubo, kubandakanywa kwi-bash, umzekelo, ngombhobho (umbhobho) odibanisa iinkqubo ezimbini, bona

[user@localhost ]$ cat /dev/zero | sleep 10000

Ungaqhuba lo myalelo ngokwakho nge umtya -f kwaye ndibone ukuba kuqhubeka ntoni ngaphakathi, kodwa ndiza kuyenza mfutshane.

Inkqubo yethu ye-bash yomzali kunye ne-PID 15771 iyahlula umyalelo wethu kwaye iqonda ngqo ukuba mingaphi imiyalelo esifuna ukuyiqhuba, kwimeko yethu kukho ezimbini zazo: ikati kunye nokulala. U-Bash uyazi ukuba kufuneka enze iinkqubo ezimbini zabantwana, kwaye zidibanise kumbhobho omnye. Iyonke, i-bash iya kufuna iinkqubo ezi-2 zomntwana kunye nombhobho omnye.

Ngaphambi kokudala iinkqubo zomntwana, i-bash iqhuba umnxeba wenkqubo umbhobho kwaye ifumana iinkcazelo zefayile entsha kwisithinteli sombhobho wethutyana, kodwa le buffer ayikaqhagamshelanisi iinkqubo zethu zabantwana ababini nangayiphi na indlela.

Kwinkqubo yomzali, kubonakala ngathi umbhobho sele ukho, kodwa akukho nkqubo yomntwana okwangoku:

PID    command
15771  bash
lrwx------ 1 user user 64 Oct  7 15:42 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:42 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:42 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:42 3 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct  7 15:42 4 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct  7 15:42 255 -> /dev/pts/21

Emva koko usebenzisa ifowuni yenkqubo Clone bash yenza iinkqubo ezimbini zabantwana, kwaye iinkqubo zethu ezintathu ziya kujongeka ngolu hlobo:

PID    command
15771  bash
lrwx------ 1 user user 64 Oct  7 15:42 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:42 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:42 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:42 3 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct  7 15:42 4 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct  7 15:42 255 -> /dev/pts/21
PID    command
9004  bash
lrwx------ 1 user user 64 Oct  7 15:57 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:57 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:57 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:57 3 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct  7 15:57 4 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct  7 15:57 255 -> /dev/pts/21
PID    command
9005  bash
lrwx------ 1 user user 64 Oct  7 15:57 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:57 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:57 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:57 3 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct  7 15:57 4 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct  7 15:57 255 -> /dev/pts/21

Ungalibali ukuba i-clone idibanisa inkqubo kunye nazo zonke izichazi zefayile, ngoko ziya kufana kwinkqubo yomzali nakubantwana. Umsebenzi wenkqubo yomzali kunye ne-PID 15771 kukubeka iliso kwiinkqubo zomntwana, ngoko ke ilindele impendulo evela kubantwana.

Ngoko ke, akafuni umbhobho, kwaye uvala iinkcazo zefayile ngeenombolo 3 kunye ne-4.

Kwinkqubo yokuqala ye-bash yomntwana kunye ne-PID 9004, ifowuni yenkqubo dup2, itshintsha ifayile ye-STDOUT yenkcazo yefayile ye-1 kwinkcazo yefayile ekhomba kumbhobho, kwimeko yethu yinombolo 3. Ngaloo ndlela, yonke into eyenziwa ngumntwana wokuqala kunye ne-PID 9004 ebhala kwi-STDOUT iya kuwela ngokuzenzekelayo kwi-buffer yombhobho.

Kwinkqubo yesibini yomntwana kunye ne-PID 9005, bash dup2s ifayile kwi-STDIN descriptor number 0. Ngoku yonke into ethi i-bash yethu yesibini kunye ne-PID 9005 iya kufunda ukusuka kumbhobho.

Emva koko, iinkcazo zefayile ezinamanani 3 kunye ne-4 nazo zivaliwe kwiinkqubo zabantwana, ekubeni zingasasetyenziswa.

Ndiyayihoya ngamabomu i-descriptor yefayile ye-255, isetyenziswe ngaphakathi nge-bash ngokwayo kwaye iya kuvalwa kwiinkqubo zabantwana.

Okulandelayo, kwinkqubo yokuqala yomntwana kunye ne-PID 9004, i-bash iqala ngomnxeba wenkqubo exec ifayile ephunyezwayo esiyichazile kumgca womyalelo, kwimeko yethu ngu/usr/bin/cat.

Kwinkqubo yomntwana wesibini kunye ne-PID 9005, i-bash iqhuba okwesibini ephunyeziweyo esiyichazile, kwimeko yethu /usr/bin/sleep.

I-exec system call ayizivali izichazi zefayile ngaphandle kokuba zivulwe nge O_CLOEXEC iflegi ngexesha lokuvula umnxeba. Kwimeko yethu, emva kokuqhuba iifayile eziphunyeziweyo, zonke iinkcazo zefayile zangoku ziya kugcinwa.

Ukujonga kwi-console:

[user@localhost ]$ pgrep -P 15771
9004
9005
[user@localhost ]$ ls -lah /proc/15771/fd/
total 0
dr-x------ 2 user user  0 Oct  7 15:42 .
dr-xr-xr-x 9 user user  0 Oct  7 15:42 ..
lrwx------ 1 user user 64 Oct  7 15:42 0 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:42 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:42 2 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:42 255 -> /dev/pts/21
[user@localhost ]$ ls -lah /proc/9004/fd
total 0
dr-x------ 2 user user  0 Oct  7 15:57 .
dr-xr-xr-x 9 user user  0 Oct  7 15:57 ..
lrwx------ 1 user user 64 Oct  7 15:57 0 -> /dev/pts/21
l-wx------ 1 user user 64 Oct  7 15:57 1 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct  7 15:57 2 -> /dev/pts/21
lr-x------ 1 user user 64 Oct  7 15:57 3 -> /dev/zero
[user@localhost ]$ ls -lah /proc/9005/fd
total 0
dr-x------ 2 user user  0 Oct  7 15:57 .
dr-xr-xr-x 9 user user  0 Oct  7 15:57 ..
lr-x------ 1 user user 64 Oct  7 15:57 0 -> pipe:[253543032]
lrwx------ 1 user user 64 Oct  7 15:57 1 -> /dev/pts/21
lrwx------ 1 user user 64 Oct  7 15:57 2 -> /dev/pts/21
[user@localhost ]$ ps -up 9004
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
user  9004  0.0  0.0 107972   620 pts/21   S+   15:57   0:00 cat /dev/zero
[user@localhost ]$ ps -up 9005
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
user  9005  0.0  0.0 107952   360 pts/21   S+   15:57   0:00 sleep 10000

Njengoko ubona, inani elikhethekileyo lombhobho wethu liyafana kuzo zombini iinkqubo. Ke, sinonxibelelwano phakathi kweenkqubo ezimbini ezahlukeneyo nomzali omnye.

Kwabo bangaqhelananga nenkqubo yokufowuna esetyenziswa yi-bash, ndincoma kakhulu ukuqhuba imiyalelo ngomtya kwaye ubone okwenzekayo ngaphakathi, umzekelo, ngolu hlobo:

strace -s 1024 -f bash -c "ls | grep hello"

Masibuyele kwingxaki yethu yokuphelelwa yindawo yedisk kwaye sizame ukugcina idatha ngaphandle kokuphinda siqalise inkqubo. Masibhale inkqubo encinci eya kubhala kwidiski malunga ne-1 megabyte ngesekhondi. Ngaphezu koko, ukuba ngenxa yesizathu esithile asikwazanga ukubhala idatha kwidiski, siya kungayihoyi le nto kwaye sizame ukubhala idatha kwakhona ngomzuzwana. Kumzekelo endiwusebenzisa iPython, ungasebenzisa naluphi na olunye ulwimi lwenkqubo.

[user@localhost ]$ cat openforwrite.py 
import datetime
import time

mystr="a"*1024*1024+"n"
with open("123.txt", "w") as f:
    while True:
        try:
            f.write(str(datetime.datetime.now()))
            f.write(mystr)
            f.flush()
            time.sleep(1)
        except:
            pass

Qhuba inkqubo kwaye ujonge izichazi zefayile

[user@localhost ]$ python openforwrite.py &
[1] 3762
[user@localhost ]$ ps axuf | grep [o]penforwrite
user  3762  0.0  0.0 128600  5744 pts/22   S+   16:28   0:00  |   _ python openforwrite.py
[user@localhost ]$ ls -la /proc/3762/fd
total 0
dr-x------ 2 user user  0 Oct  7 16:29 .
dr-xr-xr-x 9 user user  0 Oct  7 16:29 ..
lrwx------ 1 user user 64 Oct  7 16:29 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  7 16:29 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  7 16:29 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct  7 16:29 3 -> /home/user/123.txt

Njengoko ubona, sineenkcazo ezi-3 zeefayile eziqhelekileyo kunye nenye esiyivulileyo. Masijonge ubungakanani befayile:

[user@localhost ]$ ls -lah 123.txt 
-rw-rw-r-- 1 user user 117M Oct  7 16:30 123.txt

idatha ibhaliwe, sizama ukutshintsha amalungelo kwifayile:

[user@localhost ]$ sudo chown root: 123.txt
[user@localhost ]$ ls -lah 123.txt 
-rw-rw-r-- 1 root root 168M Oct  7 16:31 123.txt
[user@localhost ]$ ls -lah 123.txt 
-rw-rw-r-- 1 root root 172M Oct  7 16:31 123.txt

Siyabona ukuba idatha isabhalwa, nangona umsebenzisi wethu akanalo ilungelo lokubhalela ifayile. Masizame ukuyisusa:

[user@localhost ]$ sudo rm 123.txt 
[user@localhost ]$ ls 123.txt
ls: cannot access 123.txt: No such file or directory

Ibhalwe phi idatha? Yaye ngaba zibhaliwe kwaphela? Siyajonga:

[user@localhost ]$ ls -la /proc/3762/fd
total 0
dr-x------ 2 user user  0 Oct  7 16:29 .
dr-xr-xr-x 9 user user  0 Oct  7 16:29 ..
lrwx------ 1 user user 64 Oct  7 16:29 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  7 16:29 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  7 16:29 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct  7 16:29 3 -> /home/user/123.txt (deleted)

Ewe, inkcazo yefayile yethu isekho, kwaye sinokusebenza kunye nale fayile yenkcazo yefayile njengefayile yethu endala, sinokuyifunda, siyicoca kwaye siyikopishe.

Jonga ubungakanani befayile:

[user@localhost ]$ lsof | grep 123.txt
python    31083             user    3w      REG                8,5   19923457   2621522 /home/user/123.txt

Ubungakanani befayile ngu-19923457. Ukuzama ukucima ifayile:

[user@localhost ]$ truncate -s 0 /proc/31083/fd/3
[user@localhost ]$ lsof | grep 123.txt
python    31083             user    3w      REG                8,5  136318390   2621522 /home/user/123.txt

Njengoko ubona, ubukhulu befayile buyanda kuphela kwaye i-trunk yethu ayizange isebenze. Makhe sityhile kuxwebhu lwefowuni yesistim evulekileyo. Ukuba sisebenzisa i-O_APPEND iflegi xa uvula ifayile, ngoko ngokubhala ngamnye, inkqubo yokusebenza ihlola ubungakanani befayile kwaye ibhala idatha ukuya ekupheleni kwefayile, kwaye iyenze nge-atomically. Oku kuvumela imisonto emininzi okanye iinkqubo ukuba zibhale kwifayile enye. Kodwa kwikhowudi yethu asisebenzisi le flegi. Sinokubona ubungakanani befayile eyahlukileyo kwi-lsof emva kwesiqu kuphela ukuba sivula ifayile yokubhala, okuthetha ukuba kwikhowudi yethu, endaweni

with open("123.txt", "w") as f:

kufuneka sibeke

with open("123.txt", "a") as f:

Ukujonga nge "w" iflegi

[user@localhost ]$ strace -e trace=open python openforwrite.py 2>&1| grep 123.txt
open("123.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3

kunye ne "flegi".

[user@localhost ]$ strace -e trace=open python openforwrite.py 2>&1| grep 123.txt
open("123.txt", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3

Ukucwangcisa inkqubo esele iqhutywa

Ngokuqhelekileyo, xa usenza kwaye uvavanya inkqubo, abadwelisi beprogram basebenzisa i-debuggers (umzekelo, i-GDB) okanye amanqanaba ahlukeneyo okungena kwisicelo. I-Linux ibonelela ngokukwazi ukubhala kunye nokutshintsha inkqubo esele iqhutywa, njengokutshintsha amaxabiso ezinto eziguquguqukayo, ukuseta indawo yokuphumla, njalo njalo njalo.

Ukubuyela kumbuzo wokuqala malunga nokungabikho kwendawo yediski yokubhala ifayile, makhe sizame ukulinganisa ingxaki.

Masenze ifayile yesahlulelo sethu, esiya kunyuka njenge drive eyahlukileyo:

[user@localhost ~]$ dd if=/dev/zero of=~/tempfile_for_article.dd bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00525929 s, 2.0 GB/s
[user@localhost ~]$

Masenze inkqubo yefayile:

[user@localhost ~]$ mkfs.ext4 ~/tempfile_for_article.dd
mke2fs 1.42.9 (28-Dec-2013)
/home/user/tempfile_for_article.dd is not a block special device.
Proceed anyway? (y,n) y
...
Writing superblocks and filesystem accounting information: done
[user@localhost ~]$

Masinyuse inkqubo yefayile:

[user@localhost ~]$ sudo mount ~/tempfile_for_article.dd /mnt/
[sudo] password for user: 
[user@localhost ~]$ df -h | grep mnt
/dev/loop0      8.7M  172K  7.9M   3% /mnt

Yenza uluhlu kunye nomnini wethu:

[user@localhost ~]$ sudo mkdir /mnt/logs
[user@localhost ~]$ sudo chown user: /mnt/logs

Masivule ifayile yokubhala kuphela kwinkqubo yethu:

with open("/mnt/logs/123.txt", "w") as f:

Qalisa

[user@localhost ]$ python openforwrite.py 

Ukulinda imizuzwana embalwa

[user@localhost ~]$ df -h | grep mnt
/dev/loop0      8.7M  8.0M     0 100% /mnt

Ngoko, sifumene ingxaki echazwe ekuqaleni kweli nqaku. Indawo yasimahla 0, ithathe i-100%.

Siyakhumbula ukuba ngokwemiqathango yengxaki, sizama ukurekhoda idatha ebaluleke kakhulu engenakulahleka. Kwaye ngokwenza njalo, kufuneka silungise inkonzo ngaphandle kokuqalisa inkqubo.

Masithi sisenayo indawo yedisk, kodwa kwisahlulo esahlukileyo, umzekelo, kwi / ekhaya.

Makhe sizame "reprogram on the fly" ikhowudi yethu.

Sijonga kwi-PID yenkqubo yethu, etye yonke indawo yediski:

[user@localhost ~]$ ps axuf | grep [o]penfor
user 10078 27.2  0.0 128600  5744 pts/22   R+   11:06   0:02  |   _ python openforwrite.py

Ukuqhagamshela kwinkqubo ngegdb

[user@localhost ~]$ gdb -p 10078
...
(gdb) 

Sijonga iinkcazo zeefayile ezivulekileyo:

(gdb) shell ls -lah /proc/10078/fd/
total 0
dr-x------ 2 user user  0 Oct  8 11:06 .
dr-xr-xr-x 9 user user  0 Oct  8 11:06 ..
lrwx------ 1 user user 64 Oct  8 11:09 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:09 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:06 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct  8 11:09 3 -> /mnt/logs/123.txt

Sijonga ulwazi malunga nenkcazo yefayile enenombolo ye-3, enomdla kuthi

(gdb) shell cat /proc/10078/fdinfo/3
pos:    8189952
flags:  0100001
mnt_id: 482

Ukugcina engqondweni ukuba yeyiphi inkqubo ebizwa ngokuba yiPython (jonga ngasentla apho sibaleke khona kwaye sifumene umnxeba ovulekileyo), ngelixa sicubungula ikhowudi yethu ukuvula ifayile, senza okufanayo nathi egameni lenkqubo yethu, kodwa sifuna i-O_WRONLY|O_CREAT| O_TRUNC amasuntswana endaweni ngexabiso lamanani. Ukwenza oku, vula imithombo ye-kernel, umzekelo apha kwaye ubone ukuba zeziphi iiflegi ezinoxanduva lwantoni

#chaza i-O_WRONLY 00000001
#chaza O_CREAT 00000100
#chaza O_TRUNC 00001000

Sidibanisa onke amaxabiso kwelinye, sifumana 00001101

Ukuqhuba umnxeba wethu kwi-gdb

(gdb) call open("/home/user/123.txt", 00001101,0666)
$1 = 4

Ke sifumene inkcazo entsha yefayile enenombolo 4 kunye nefayile entsha evulekileyo kwesinye isahlulelo, khangela:

(gdb) shell ls -lah /proc/10078/fd/
total 0
dr-x------ 2 user user  0 Oct  8 11:06 .
dr-xr-xr-x 9 user user  0 Oct  8 11:06 ..
lrwx------ 1 user user 64 Oct  8 11:09 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:09 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:06 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct  8 11:09 3 -> /mnt/logs/123.txt
l-wx------ 1 user user 64 Oct  8 11:15 4 -> /home/user/123.txt

Sikhumbula umzekelo ngombhobho - indlela i-bash etshintsha ngayo izichazi zefayile, kwaye sele sifunde i-dup2 inkqubo yokufowuna.

Izama ukubuyisela enye ingcaciso yefayile enye

(gdb) call dup2(4,3)
$2 = 3

Ukuhlola:

(gdb) shell ls -lah /proc/10078/fd/
total 0
dr-x------ 2 user user  0 Oct  8 11:06 .
dr-xr-xr-x 9 user user  0 Oct  8 11:06 ..
lrwx------ 1 user user 64 Oct  8 11:09 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:09 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:06 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct  8 11:09 3 -> /home/user/123.txt
l-wx------ 1 user user 64 Oct  8 11:15 4 -> /home/user/123.txt

Vala isichazi sefayile 4, kuba asiyifuni:

(gdb) call close (4)
$1 = 0

Kwaye uphume kwi-gdb

(gdb) quit
A debugging session is active.

    Inferior 1 [process 10078] will be detached.

Quit anyway? (y or n) y
Detaching from program: /usr/bin/python2.7, process 10078

Ijonga ifayile entsha:

[user@localhost ~]$ ls -lah /home/user/123.txt
-rw-rw-r-- 1 user user 5.1M Oct  8 11:18 /home/user/123.txt
[user@localhost ~]$ ls -lah /home/user/123.txt
-rw-rw-r-- 1 user user 7.1M Oct  8 11:18 /home/user/123.txt

Njengoko ubona, idatha ibhalwe kwifayile entsha, sijonga endala:

[user@localhost ~]$ ls -lah /mnt/logs/123.txt 
-rw-rw-r-- 1 user user 7.9M Oct  8 11:08 /mnt/logs/123.txt

Idatha ayilahlekanga, isicelo sisebenza, iilogi zibhalwa kwindawo entsha.

Masenze izinto zibenzima ngakumbi

Khawucinge ukuba idatha ibalulekile kuthi, kodwa asinayo indawo yediski kuyo nayiphi na isahlulo kwaye asikwazi ukudibanisa idiski.

Into esinokuyenza kukubuyisela idatha yethu kwenye indawo, umzekelo, kumbhobho, kwaye uqondise kwakhona idatha ukusuka kumbhobho ukuya kwinethiwekhi ngokusebenzisa inkqubo ethile, njenge-netcat.
Singenza umbhobho onegama ngomyalelo we-mkfifo. Iyakwenza ifayile yepseudo kwindlela yefayile, nokuba akukho ndawo yasimahla kuyo.

Qala kwakhona isicelo kwaye ujonge:

[user@localhost ]$ python openforwrite.py 
[user@localhost ~]$ ps axuf | grep [o]pen
user  5946 72.9  0.0 128600  5744 pts/22   R+   11:27   0:20  |   _ python openforwrite.py
[user@localhost ~]$ ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user  0 Oct  8 11:27 .
dr-xr-xr-x 9 user user  0 Oct  8 11:27 ..
lrwx------ 1 user user 64 Oct  8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct  8 11:28 3 -> /mnt/logs/123.txt
[user@localhost ~]$ df -h | grep mnt
/dev/loop0      8.7M  8.0M     0 100% /mnt

Akukho ndawo yedisk, kodwa senza ngempumelelo umbhobho ogama apho:

[user@localhost ~]$ mkfifo /mnt/logs/megapipe
[user@localhost ~]$ ls -lah /mnt/logs/megapipe 
prw-rw-r-- 1 user user 0 Oct  8 11:28 /mnt/logs/megapipe

Ngoku kufuneka ngandlela thile sisonge yonke idatha engena kulo mbhobho kwenye iseva ngenethiwekhi, i-netcat efanayo ifanelekile oku.

Kwi-remote-server.example.com iseva, sebenzisa

[user@localhost ~]$ nc -l 7777 > 123.txt 

Kwiseva yethu yengxaki, sebenzisa i-terminal eyahlukileyo

[user@localhost ~]$ nc remote-server.example.com 7777 < /mnt/logs/megapipe 

Ngoku yonke idatha engena kumbhobho iya ngokuzenzekelayo ukuya kwi-stdin kwi-netcat, eya kuyithumela kwinethiwekhi kwi-port 7777.

Konke okufuneka sikwenze kukuqala ukubhala idatha yethu kulo mbhobho ogama lingu.

Sele sinesicelo esisebenzayo:

[user@localhost ~]$ ps axuf | grep [o]pen
user  5946 99.8  0.0 128600  5744 pts/22   R+   11:27 169:27  |   _ python openforwrite.py
[user@localhost ~]$ ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user  0 Oct  8 11:27 .
dr-xr-xr-x 9 user user  0 Oct  8 11:27 ..
lrwx------ 1 user user 64 Oct  8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct  8 11:28 3 -> /mnt/logs/123.txt

Kuzo zonke iiflegi, sifuna kuphela i-O_WRONLY kuba ifayile sele ikhona kwaye akukho mfuneko yokuba siyicime.

[user@localhost ~]$ gdb -p 5946
...
(gdb) call open("/mnt/logs/megapipe", 00000001,0666)
$1 = 4
(gdb) shell ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user  0 Oct  8 11:27 .
dr-xr-xr-x 9 user user  0 Oct  8 11:27 ..
lrwx------ 1 user user 64 Oct  8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct  8 11:28 3 -> /mnt/logs/123.txt
l-wx------ 1 user user 64 Oct  8 14:20 4 -> /mnt/logs/megapipe
(gdb) call dup2(4,3)
$2 = 3
(gdb) shell ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user  0 Oct  8 11:27 .
dr-xr-xr-x 9 user user  0 Oct  8 11:27 ..
lrwx------ 1 user user 64 Oct  8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct  8 11:28 3 -> /mnt/logs/megapipe
l-wx------ 1 user user 64 Oct  8 14:20 4 -> /mnt/logs/megapipe
(gdb) call close(4)
$3 = 0
(gdb) shell ls -lah /proc/5946/fd
total 0
dr-x------ 2 user user  0 Oct  8 11:27 .
dr-xr-xr-x 9 user user  0 Oct  8 11:27 ..
lrwx------ 1 user user 64 Oct  8 11:28 0 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:28 1 -> /dev/pts/22
lrwx------ 1 user user 64 Oct  8 11:27 2 -> /dev/pts/22
l-wx------ 1 user user 64 Oct  8 11:28 3 -> /mnt/logs/megapipe
(gdb) quit
A debugging session is active.

    Inferior 1 [process 5946] will be detached.

Quit anyway? (y or n) y
Detaching from program: /usr/bin/python2.7, process 5946

Ijonga iseva ekude-server.example.com

[user@localhost ~]$ ls -lah 123.txt 
-rw-rw-r-- 1 user user 38M Oct  8 14:21 123.txt

Idatha iyeza, sijonga iseva yengxaki

[user@localhost ~]$ ls -lah /mnt/logs/
total 7.9M
drwxr-xr-x 2 user user 1.0K Oct  8 11:28 .
drwxr-xr-x 4 root     root     1.0K Oct  8 10:55 ..
-rw-rw-r-- 1 user user 7.9M Oct  8 14:17 123.txt
prw-rw-r-- 1 user user    0 Oct  8 14:22 megapipe

Idatha igcinwe, ingxaki isonjululwe.

Ndithatha eli thuba ukubulisa koogxa bam baseDegiro.
Mamela iipodcasts zeRadio-T.

Zonke zilungile.

Njengomsebenzi wasekhaya, ndicebisa ukuba ndicinge malunga nokuba kuya kuba yintoni kwizichazi zefayile zekati kunye nenkqubo yokulala ukuba usebenzisa lo myalelo ulandelayo:

[user@localhost ~]$ cat /dev/zero 2>/dev/null| sleep 10000

umthombo: www.habr.com

Yongeza izimvo