Mai kwatanta fayil a cikin Linux tare da misalai

Sau ɗaya, yayin hira, an tambaye ni, me za ku yi idan kun sami sabis ɗin ba ya aiki saboda gaskiyar cewa diski ya ƙare?

Tabbas, na amsa cewa zan ga abin da wannan wurin ya mamaye kuma, idan zai yiwu, zan share wurin.
Sai mai tambayoyin ya tambaya, menene idan babu sarari kyauta akan partition, amma kuma ba ku ga wani fayil ɗin da zai ɗauki sararin samaniya ba?

Don wannan na ce koyaushe za ku iya duba bayanan buɗaɗɗen fayil, misali tare da umarnin lsof, kuma ku fahimci wane aikace-aikacen ya ɗauki duk sararin da ke akwai, sannan zaku iya aiki daidai da yanayin, gwargwadon ko ana buƙatar bayanan. .

Mai tambayoyin ya katse ni a kan kalma ta ƙarshe, yana ƙara tambayarsa: "A ce ba ma buƙatar bayanan, kawai rajistan kuskure ne, amma aikace-aikacen ba ya aiki saboda ba zai iya rubuta kuskure ba"?

"Ok," na amsa, "zamu iya kashe debug a cikin saitin aikace-aikacen mu sake kunna shi."
Mai tambayoyin ya ƙi cewa: "A'a, ba za mu iya sake kunna aikace-aikacen ba, har yanzu muna da mahimman bayanai da aka adana a ƙwaƙwalwar ajiya, kuma mahimman abokan ciniki suna da alaƙa da sabis ɗin kanta, waɗanda ba za mu iya tilasta sake haɗawa ba."

Na ce, "lafiya," in ce, "idan ba za mu iya sake kunna aikace-aikacen ba kuma bayanan ba su da mahimmanci a gare mu, to za mu iya kawai share wannan buɗaɗɗen fayil ta hanyar bayanin fayil, koda kuwa ba mu gan shi a cikin umarnin ls ba. a tsarin fayil."

Mai tambayoyin ya ji daɗi, amma ban ji ba.

Sai na yi tunani, me ya sa mutumin da ke gwada ilimina ba ya zurfafa zurfafawa? Amma menene idan bayanan suna da mahimmanci bayan duk? Me zai faru idan ba za mu iya sake farawa wani tsari ba, kuma tsarin ya rubuta zuwa tsarin fayil akan ɓangaren da ba shi da sarari kyauta? Idan ba za mu iya rasa ba kawai bayanan da aka riga aka rubuta ba, har ma da bayanan da wannan tsari ya rubuta ko ƙoƙarin rubutawa?

Tuzik

A farkon aikina, na yi ƙoƙarin ƙirƙirar ƙaramin aikace-aikacen da ke buƙatar adana bayanan mai amfani. Sai na yi tunani, ta yaya zan iya daidaita mai amfani da bayanansa. Alal misali, Ina da Ivanov Ivan Ivanovich, kuma yana da wasu bayanai, amma ta yaya zan iya yin abokai da su? Zan iya nuna kai tsaye cewa kare mai suna "Tuzik" na cikin wannan Ivan. Amma idan ya canza sunansa kuma maimakon Ivan ya zama, alal misali, Olya? Sa'an nan kuma zai zama cewa mu Olya Ivanovna Ivanova ba za su sake samun kare ba, kuma Tuzik ɗinmu zai kasance cikin Ivan da ba shi da shi. Rubutun bayanai wanda ya ba kowane mai amfani da mai ganowa na musamman (ID) ya taimaka wajen magance wannan matsala, kuma Tuzik na yana daura da wannan ID, wanda, a gaskiya, lamba ce kawai. Don haka, mai ace yana da lambar ID 2, kuma a wani lokaci Ivan yana ƙarƙashin wannan ID, sa'an nan Olya ya zama ƙarƙashin ID ɗaya. An magance matsalar ɗan adam da kiwo a zahiri.

Mai kwatanta fayil

Matsalar fayil ɗin da shirin da ke aiki tare da wannan fayil kusan iri ɗaya ne da na kare da mutuminmu. A ce na bude fayil mai suna ivan.txt na fara rubuta kalmar tuzik a ciki, amma kawai na sami damar rubuta harafin farko "t" a cikin fayil ɗin, kuma wani ya canza sunan wannan fayil, misali, olya.txt. Amma fayil ɗin ya kasance iri ɗaya, kuma har yanzu ina son yin rikodin ace na a ciki. Duk lokacin da aka buɗe fayil ta hanyar kiran tsarin bude a cikin kowane yaren shirye-shirye na karɓi ID na musamman wanda ke nuna ni zuwa fayil, wannan ID ɗin shine bayanin fayil. Kuma ba komai ko mene ne kuma wa zai yi da wannan fayil na gaba, ana iya goge shi, a canza masa suna, a canza mai shi, ko kuma a kwace hakkin karatu da rubutu, zan samu damar shiga. zuwa gare shi, domin a lokacin buɗe fayil ɗin, Ina da haƙƙin karantawa da / ko rubuta shi kuma na sami damar fara aiki da shi, wanda ke nufin dole ne in ci gaba da yin hakan.

A cikin Linux, ɗakin karatu na libc yana buɗe fayilolin siffantawa 3 don kowane aikace-aikacen (tsari), mai lamba 0,1,2. Ana iya samun ƙarin bayani akan hanyoyin haɗin gwiwa man stdio и mutum stdout

  • Ana kiran mai bayanin fayil 0 STDIN kuma yana da alaƙa da shigar da aikace-aikacen
  • Mai siffanta fayil 1 ana kiransa STDOUT kuma aikace-aikace ne ke amfani dashi don fitar da bayanai, kamar umarnin bugawa
  • Ana kiran mai bayanin fayil 2 STDERR kuma aikace-aikace ne ke amfani dashi don fitar da saƙon kuskure.

Idan a cikin shirin ku ka buɗe kowane fayil don karantawa ko rubutu, to tabbas za ku sami ID na farko na kyauta kuma zai zama lamba 3.

Za a iya duba lissafin masu siffanta fayil don kowane tsari idan kun san PID ɗin sa.

Misali, bari mu bude bash console mu dubi PID na tsarin mu

[user@localhost ]$ echo $$
15771

A cikin na'ura wasan bidiyo na biyu bari mu gudu

[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

Kuna iya yin watsi da lambar bayanin fayil mai lamba 255 cikin aminci don dalilan wannan labarin; an buɗe shi don buƙatun sa ta bash da kanta, ba ta hanyar ɗakin karatu ba.

Yanzu duk fayilolin bayanin guda 3 suna da alaƙa da na'urar tasha /dev/pts, amma har yanzu muna iya sarrafa su, misali, gudanar da su a cikin na'ura mai kwakwalwa ta biyu

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

Kuma a farkon wasan bidiyo za mu gani

[user@localhost ]$ hello world

Komawa da Bututu

Kuna iya sauƙaƙe waɗannan fayilolin bayanin guda 3 a cikin kowane tsari, gami da a cikin bash, misali ta hanyar bututu mai haɗa hanyoyin guda biyu, duba.

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

Kuna iya gudanar da wannan umarni da kanku zare -f kuma ga abin da ke faruwa a ciki, amma zan gaya muku a takaice.

Tsarin bash na iyayenmu tare da PID 15771 yana ba da umarnin mu kuma ya fahimci ainihin umarni nawa muke son aiwatarwa, a cikin yanayinmu akwai biyu daga cikinsu: cat da barci. Bash ya san cewa yana buƙatar ƙirƙirar matakan yara biyu, kuma ya haɗa su cikin bututu ɗaya. Gabaɗaya, bash zai buƙaci matakan yara 2 da bututu ɗaya.

Bash yana gudanar da kiran tsarin kafin ƙirƙirar matakan yara bututu kuma yana karɓar sabbin bayanan bayanan fayil akan buffer na wucin gadi, amma wannan buffer ɗin bai riga ya haɗa matakan yaran mu biyu ba.

Ga tsarin iyaye, yana kama da an riga an sami bututu, amma babu matakan yara tukuna:

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

Sannan amfani da tsarin kira clone bash yana haifar da tsarin yara guda biyu, kuma tsarin mu guda uku zai yi kama da haka:

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

Kar ka manta cewa clone clone tsarin tare da duk fayilolin fayiloli, don haka za su kasance iri ɗaya a cikin tsarin iyaye da kuma a cikin yara. Ayyukan tsarin iyaye tare da PID 15771 shine saka idanu kan matakan yara, don haka kawai yana jiran amsa daga yara.

Saboda haka, ba ya buƙatar bututu, kuma yana rufe bayanan fayil mai lamba 3 da 4.

A cikin tsarin bash na farko na yara tare da PID 9004, tsarin yana kira dup2, yana canza bayanin fayil ɗin mu na STDOUT lamba 1 zuwa mai siffanta fayil yana nuna bututu, a yanayin mu shine lamba 3. Don haka, duk abin da yaro na farko ya aiwatar da PID 9004 ya rubuta wa STDOUT zai ƙare kai tsaye a cikin buffer.

A cikin tsarin yara na biyu tare da PID 9005, bash yana amfani da dup2 don canza bayanin fayil ɗin STDIN lambar 0. Yanzu duk abin da bash ɗin mu na biyu tare da PID 9005 za a karanta daga bututu.

Bayan haka, ana kuma rufe masu bayanin fayil mai lamba 3 da 4 a cikin ayyukan yara, tunda ba a amfani da su.

Na yi watsi da bayanin fayil 255 da gangan; ana amfani da shi don dalilai na ciki ta bash kanta kuma za a rufe shi a cikin tsarin yara.

Na gaba, a cikin tsarin yara na farko tare da PID 9004, bash yana fara amfani da kiran tsarin exec fayil ɗin aiwatarwa wanda muka ƙayyade akan layin umarni, a cikin yanayin mu shine /usr/bin/cat.

A cikin tsarin yara na biyu tare da PID 9005, bash yana aiwatar da aiwatarwa na biyu da muka ayyana, a cikin yanayin mu /usr/bin/barci.

Kiran tsarin tsarin ba ya rufe hanun fayil sai dai idan an buɗe su da tutar O_CLOEXEC a lokacin buɗe kiran. A cikin yanayinmu, bayan ƙaddamar da fayilolin da za a iya aiwatarwa, za a adana duk kwatancen fayil ɗin na yanzu.

Duba cikin na'ura mai kwakwalwa:

[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

Kamar yadda kake gani, lambar musamman na bututunmu iri ɗaya ne a cikin matakai biyu. Don haka muna da alaƙa tsakanin matakai daban-daban guda biyu tare da iyaye ɗaya.

Ga waɗanda ba su saba da tsarin kiran tsarin da bash ke amfani da shi ba, Ina ba da shawarar yin amfani da umarni ta hanyar layi da ganin abin da ke faruwa a ciki, misali kamar haka:

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

Bari mu koma ga matsalarmu tare da ƙananan sararin faifai da ƙoƙarin adana bayanai ba tare da sake farawa ba. Bari mu rubuta ƙaramin shirin da zai rubuta kusan megabyte 1 a sakan daya zuwa faifai. Bugu da ƙari, idan saboda wasu dalilai ba mu iya rubuta bayanai zuwa faifai ba, za mu yi watsi da wannan kawai kuma mu sake ƙoƙarin rubuta bayanan a cikin daƙiƙa guda. A cikin misalin da nake amfani da Python, kuna iya amfani da kowane yaren shirye-shirye.

[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

Bari mu gudanar da shirin kuma mu dubi masu bayanin fayil

[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

Kamar yadda kake gani, muna da daidaitattun fayilolin mu guda 3 da kuma ƙarin wanda muka buɗe. Bari mu duba girman fayil:

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

Ana rubuta bayanan, muna ƙoƙarin canza izini akan fayil ɗin:

[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

Mun ga cewa har yanzu ana rubuta bayanan, kodayake mai amfani da mu ba shi da izinin rubutawa zuwa fayil ɗin. Mu yi kokarin cire shi:

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

Ina aka rubuta bayanan? Kuma an rubuta su kwata-kwata? Muna duba:

[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)

Ee, bayanin fayil ɗin mu har yanzu yana nan kuma zamu iya ɗaukar wannan sifan fayilolin kamar tsohon fayil ɗin mu, zamu iya karantawa, sharewa da kwafi shi.

Bari mu dubi girman fayil ɗin:

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

Girman fayil ɗin shine 19923457. Bari muyi ƙoƙarin share fayil ɗin:

[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

Kamar yadda kake gani, girman fayil ɗin yana ƙaruwa ne kawai kuma gangar jikinmu bai yi aiki ba. Bari mu dubi takardun kiran tsarin bude. Idan muka yi amfani da tutar O_APPEND lokacin buɗe fayil, sannan tare da kowane rubutu, tsarin aiki yana duba girman fayil ɗin kuma ya rubuta bayanai zuwa ƙarshen fayil ɗin, kuma yana yin hakan ta atomatik. Wannan yana ba da damar zaren ko matakai da yawa don rubutawa zuwa fayil iri ɗaya. Amma a cikin lambar mu ba ma amfani da wannan tuta. Za mu iya ganin girman fayil daban-daban a cikin lsof bayan akwati kawai idan muka buɗe fayil ɗin don ƙarin rubutu, wanda ke nufin a cikin lambar mu maimakon haka.

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

dole mu saka

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

Dubawa da alamar "w".

[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

kuma tare da "a" flag

[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

Shirya tsari wanda ya riga ya gudana

Sau da yawa masu shirye-shirye, lokacin ƙirƙira da gwada shirye-shiryen, suna amfani da debuggers (misali GDB) ko matakai daban-daban na shiga cikin aikace-aikacen. Linux yana ba da ikon rubutawa da canza shirin da ya riga ya gudana, alal misali, canza ƙimar masu canji, saita wurin hutu, da sauransu, da sauransu.

Komawa ga ainihin tambayar game da rashin isasshen sarari don rubuta fayil, bari mu yi ƙoƙarin daidaita matsalar.

Bari mu ƙirƙiri fayil don ɓangarenmu, wanda za mu hau a matsayin faifai daban:

[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 ~]$

Bari mu ƙirƙiri tsarin fayil:

[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 ~]$

Haɗa tsarin fayil:

[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

Mun ƙirƙiri kundin adireshi tare da mai mu:

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

Bari mu buɗe fayil ɗin don rubutawa kawai a cikin shirinmu:

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

Kaddamarwa

[user@localhost ]$ python openforwrite.py 

Muna jira 'yan dakiku

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

Don haka, muna da matsalar da aka kwatanta a farkon wannan labarin. sarari kyauta 0, an shagaltar da 100%.

Mun tuna cewa bisa ga yanayin aikin, muna ƙoƙarin yin rikodin mahimman bayanai waɗanda ba za a iya rasa ba. Kuma a lokaci guda, muna buƙatar gyara sabis ɗin ba tare da sake kunna tsarin ba.

Bari mu ce har yanzu muna da sarari diski, amma a cikin wani bangare daban, misali a / gida.

Bari mu yi kokarin "reprogram a kan gardama" mu code.

Bari mu kalli PID na tsarinmu, wanda ya cinye duk sararin diski:

[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

Haɗa zuwa tsari ta hanyar gdb

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

Bari mu dubi buɗaɗɗen bayanin bayanin fayil:

(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

Muna kallon bayanin game da lambar bayanin fayil 3, wanda ke sha'awar mu

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

Tuna da tsarin tsarin da ake kira Python (duba sama inda muka gudu muka sami buɗaɗɗen kira), lokacin sarrafa lambar mu don buɗe fayil, haka kanmu muke yi a madadin tsarinmu, amma muna buƙatar O_WRONLY|O_CREAT| O_TRUNC ragowa suna maye gurbinsu da ƙimar lamba. Don yin wannan, buɗe tushen kwaya, misali a nan kuma a duba wane tutoci ke da alhakin me

# ayyana O_WRONLY 00000001
# ayyana O_CREAT 00000100
# ayyana O_TRUNC 00001000

Mun hada dukkan dabi'u zuwa daya, muna samun 00001101

Muna gudanar da kiran mu daga gdb

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

Don haka mun sami sabon bayanin fayil mai lamba 4 da sabon fayil ɗin buɗewa akan wani bangare, muna duba:

(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

Muna tunawa da misali tare da bututu - yadda bash ke canza fayilolin fayiloli, kuma mun riga mun koyi tsarin tsarin dup2.

Muna ƙoƙari mu maye gurbin bayanin fayil ɗaya da wani

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

Binciken:

(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

Muna rufe bayanin fayil 4, tunda ba ma buƙatarsa:

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

Kuma fita 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

Duba sabon fayil:

[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

Kamar yadda kake gani, an rubuta bayanan zuwa sabon fayil, bari mu duba tsohon:

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

Babu bayanai da suka ɓace, aikace-aikacen yana aiki, ana rubuta rajistan ayyukan zuwa sabon wuri.

Bari mu dagula aikin kadan

Bari mu yi tunanin cewa bayanan suna da mahimmanci a gare mu, amma ba mu da sararin faifai a cikin kowane bangare kuma ba za mu iya haɗa faifai ba.

Abin da za mu iya yi shi ne mu karkatar da bayananmu a wani wuri, misali zuwa bututu, sannan kuma a tura bayanai daga bututu zuwa hanyar sadarwa ta hanyar wasu shirye-shirye, misali netcat.
Za mu iya ƙirƙirar bututu mai suna tare da umarnin mkfifo. Zai ƙirƙiri fayil ɗin ƙirƙira akan tsarin fayil ko da babu sarari kyauta akansa.

Sake kunna aikace-aikacen kuma duba:

[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

Babu sarari diski, amma mun sami nasarar ƙirƙirar bututu mai suna a wurin:

[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

Yanzu muna buƙatar ko ta yaya mu naɗa duk bayanan da ke shiga cikin wannan bututu zuwa wani sabar ta hanyar hanyar sadarwa; netcat iri ɗaya ya dace da wannan.

A kan uwar garken remote-server.example.com muna aiki

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

A kan uwar garken matsalarmu muna ƙaddamar a cikin wani tasha ta daban

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

Yanzu duk bayanan da ke ƙarewa a cikin bututu za su tafi kai tsaye zuwa stdin a cikin netcat, wanda zai aika shi zuwa hanyar sadarwa akan tashar jiragen ruwa 7777.

Abin da za mu yi shi ne mu fara rubuta bayanan mu a cikin wannan bututu mai suna.

Mun riga muna da aikace-aikacen yana gudana:

[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

Daga cikin dukkan tutocin, O_WRONLY kawai muke bukata tunda fayil ɗin ya riga ya wanzu kuma ba ma buƙatar share shi

[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

Dubawa uwar garken nesa remote-server.example.com

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

Bayanan yana zuwa, muna duba uwar garken matsala

[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

An adana bayanan, an magance matsalar.

Ina amfani da wannan damar in gaishe da abokan aikina daga Degiro.
Saurari kwasfan fayiloli na Rediyo-T.

Yayi kyau ga duka.

A matsayin aikin gida, Ina ba da shawarar ku yi tunani game da abin da zai kasance a cikin tsarin fayilolin mai bayyana cat da barci idan kun gudanar da umarni mai zuwa:

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

source: www.habr.com

Add a comment