Deskriptor file ing Linux kanthi conto

Sawise, nalika wawancara, aku ditakoni, apa sing bakal sampeyan lakoni yen sampeyan nemokake layanan sing ora bisa digunakake amarga disk wis entek spasi?

Mesthi wae, aku mangsuli yen aku bakal weruh apa sing dikuwasani ing papan iki lan, yen bisa, aku bakal ngresiki papan kasebut.
Banjur pewawancara takon, kepiye yen ora ana ruang kosong ing partisi, nanging sampeyan uga ora weruh file sing bakal njupuk kabeh ruang?

Iki aku ngandika sing bisa tansah katon ing deskriptor file mbukak, contone karo printah lsof, lan ngerti aplikasi kang wis njupuk kabeh papan sing kasedhiya, banjur sampeyan bisa tumindak miturut kahanan, gumantung ing apa data dibutuhake. .

Interviewer nyelani kula ing tembung pungkasan, nambah kanggo pitakonan kang: "Mungkin kita ora perlu data, iku mung log debug, nanging aplikasi ora bisa amarga ora bisa nulis debug"?

"Oke," wangsulanku, "kita bisa mateni debug ing konfigurasi aplikasi lan miwiti maneh."
Pewawancara mbantah: "Ora, kita ora bisa miwiti maneh aplikasi, kita isih duwe data penting sing disimpen ing memori, lan klien penting disambungake menyang layanan kasebut, sing ora bisa dipeksa kanggo nyambung maneh."

"Oke," ujarku, "yen kita ora bisa miwiti maneh aplikasi lan data ora penting kanggo kita, mula kita bisa mbusak file sing mbukak iki liwat deskriptor file, sanajan kita ora ndeleng ing perintah ls. ing sistem file."

Interviewer seneng, nanging aku ora.

Banjur aku mikir, kenapa wong kasebut ora nguji kawruhku luwih jero? Nanging apa yen data penting sawise kabeh? Apa yen kita ora bisa miwiti maneh proses, lan proses nulis menyang sistem file ing partisi sing ora duwe ruang kosong? Apa yen kita ora bisa ilang ora mung data sing wis ditulis, nanging uga data sing proses iki nulis utawa nyoba nulis?

Tuzik

Ing awal karir, aku nyoba nggawe aplikasi cilik sing perlu kanggo nyimpen informasi pangguna. Banjur aku mikir, kepiye carane bisa cocog karo pangguna karo data kasebut. Contone, aku duwe Ivanov Ivan Ivanovich, lan dheweke duwe sawetara informasi, nanging kepiye carane aku bisa nggawe kanca karo dheweke? Aku bisa langsung nuduhake yen asu sing jenenge "Tuzik" kalebu Ivan iki. Nanging apa yen ngganti jeneng lan tinimbang Ivan dadi, contone, Olya? Banjur bakal katon yen Olya Ivanovna Ivanova ora bakal duwe asu maneh, lan Tuzik kita isih dadi Ivan sing ora ana. Database sing menehi saben pangguna pengenal unik (ID) mbantu ngatasi masalah iki, lan Tuzik saya disambungake menyang ID iki, sing, nyatane, mung nomer serial. Mangkono, pemilik ace duwe ID nomer 2, lan ing sawetara wektu Ivan ana ing ID iki, lan banjur Olya dadi ing ID padha. Masalah manungsa lan peternakan wis ditanggulangi kanthi praktis.

Deskriptor file

Masalah file lan program sing bisa digunakake karo file iki kira-kira padha karo asu lan manungsa. Upamane aku mbukak file sing diarani ivan.txt lan wiwit nulis tembung tuzik, nanging mung bisa nulis huruf pisanan "t" ing file kasebut, lan file iki diganti jeneng dening wong, contone, dadi olya.txt. Nanging file tetep padha, lan aku isih pengin ngrekam ace ing. Saben file dibukak dening sistem telpon mbukak ing sembarang basa program aku nampa ID unik sing nuduhake kula menyang file, ID iki deskriptor file. Lan ora masalah apa-apa lan sapa sing nindakake file iki sabanjure, bisa dibusak, bisa diganti jeneng, pemilik bisa diganti, utawa hak maca lan nulis bisa dicopot, aku isih duwe akses. kanggo, amarga ing wektu mbukak file, aku duwe hak kanggo maca lan / utawa nulis lan aku bisa miwiti nggarap, kang tegese aku kudu terus nglakoni.

Ing Linux, perpustakaan libc mbukak 3 file deskriptor kanggo saben aplikasi sing mlaku (proses), kanthi nomer 0,1,2. Informasi liyane bisa ditemokake ing pranala wong stdio ΠΈ wong stdout

  • Deskriptor file 0 diarani STDIN lan digandhengake karo input aplikasi
  • Deskriptor file 1 diarani STDOUT lan digunakake dening aplikasi kanggo ngasilake data, kayata printah printah
  • Deskriptor file 2 diarani STDERR lan digunakake dening aplikasi kanggo ngirim pesen kesalahan.

Yen ing program sampeyan mbukak file apa wae kanggo maca utawa nulis, mesthine sampeyan bakal entuk ID gratis pertama lan bakal dadi nomer 3.

Dhaptar deskriptor file bisa dideleng kanggo proses apa wae yen sampeyan ngerti PID.

Contone, ayo mbukak konsol bash lan deleng PID proses kita

[user@localhost ]$ echo $$
15771

Ing console kapindho ayo mbukak

[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

Sampeyan bisa kanthi aman nglirwakake deskriptor file nomer 255 kanggo tujuan artikel iki; iki dibukak kanggo kabutuhan kanthi bash dhewe, lan dudu perpustakaan sing disambung.

Saiki kabeh 3 file deskriptor digandhengake karo piranti terminal pseudo /dev/pts, nanging kita isih bisa ngapusi wong, contone, mbukak ing console kapindho

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

Lan ing console pisanan kita bakal weruh

[user@localhost ]$ hello world

Pangalihan lan Pipa

Sampeyan bisa gampang ngilangi 3 file deskriptor iki ing proses apa wae, kalebu ing bash, contone liwat pipa sing nyambungake rong proses, deleng

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

Sampeyan bisa mbukak printah iki dhewe karo strata -f lan ndeleng apa mengkono nang, nanging aku bakal pitutur marang kowe sedhela.

Proses bash wong tuwa kita karo PID 15771 parses printah kita lan ngerti persis carane akeh printah kita arep kanggo mbukak, ing kasus kita ana loro: kucing lan turu. Bash ngerti yen kudu nggawe rong proses anak, lan gabungke dadi siji pipa. Secara total, bash mbutuhake 2 proses anak lan siji pipa.

Bash nglakokake telpon sistem sadurunge nggawe proses anak Pipa lan nampa deskriptor file anyar ing buffer pipe sauntara, nanging buffer iki durung nyambung loro pangolahan anak kita.

Kanggo proses wong tuwa, kayane wis ana pipa, nanging durung ana proses anak:

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

Banjur nggunakake telpon sistem Klone bash nggawe rong proses anak, lan telung proses kita bakal katon kaya iki:

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

Aja lali yen clone proses bebarengan karo kabeh deskriptor file, supaya padha ing proses wong tuwa lan ing anak. Tugas proses wong tuwa karo PID 15771 yaiku ngawasi proses anak, mula mung ngenteni respon saka bocah-bocah.

Mulane, ora perlu pipa, lan nutup deskriptor file nomer 3 lan 4.

Ing proses bash anak pisanan karo PID 9004, telpon sistem dup2, ngganti deskriptor file STDOUT kita nomer 1 dadi deskriptor file sing ngarah menyang pipa, ing kasus kita nomer 3. Mangkono, kabeh sing proses anak pisanan karo PID 9004 nulis STDOUT bakal kanthi otomatis rampung ing buffer pipa.

Ing proses anak kaping pindho karo PID 9005, bash nggunakake dup2 kanggo ngganti deskriptor file STDIN nomer 0. Saiki kabeh sing bakal diwaca bash kapindho karo PID 9005 bakal diwaca saka pipa.

Sawise iki, deskriptor file nomer 3 lan 4 uga ditutup ing proses anak, amarga ora digunakake maneh.

Aku sengaja nglirwakake deskriptor file 255; digunakake kanggo tujuan internal kanthi bash dhewe lan uga bakal ditutup ing proses anak.

Sabanjure, ing proses anak pisanan karo PID 9004, bash wiwit nggunakake panggilan sistem exec file eksekusi sing ditemtokake ing baris perintah, ing kasus kita yaiku /usr/bin/cat.

Ing proses anak nomer loro karo PID 9005, bash mbukak eksekusi kapindho sing ditemtokake, ing kasus kita /usr/bin/sleep.

Telpon sistem exec ora nutup gagang file kajaba padha dibukak nganggo gendΓ©ra O_CLOEXEC nalika telpon mbukak digawe. Ing kasus kita, sawise mbukak file eksekusi, kabeh deskriptor file saiki bakal disimpen.

Priksa ing konsol:

[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

Nalika sampeyan bisa ndeleng, nomer unik saka pipe kita padha ing loro pangolahan. Mangkono kita duwe sambungan antarane rong proses beda karo wong tuwa sing padha.

Kanggo sing ora kenal karo sistem panggilan sing digunakake bash, aku menehi saran supaya bisa nglakokake perintah liwat strace lan ndeleng apa sing kedadeyan ing njero, umpamane kaya iki:

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

Ayo bali menyang masalah karo ruang disk sing sithik lan nyoba nyimpen data tanpa miwiti maneh proses kasebut. Ayo nulis program cilik sing bakal nulis kira-kira 1 megabyte per detik menyang disk. Kajaba iku, yen ana alesan ora bisa nulis data menyang disk, kita mung bakal nglirwakake iki lan nyoba nulis data maneh ing detik. Ing conto aku nggunakake Python, sampeyan bisa nggunakake basa program liyane.

[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

Ayo mbukak program lan deleng deskriptor file

[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

Kaya sing sampeyan ngerteni, kita duwe 3 deskriptor file standar lan siji liyane sing dibukak. Ayo priksa ukuran file:

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

Data lagi ditulis, kita nyoba ngganti ijin ing file:

[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

Kita weruh manawa data kasebut isih ditulis, sanajan pangguna ora duwe ijin kanggo nulis menyang file kasebut. Ayo nyoba mbusak:

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

Ing ngendi data kasebut ditulis? Lan padha ditulis ing kabeh? Kita mriksa:

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

Ya, deskriptor file kita isih ana lan kita bisa nambani deskriptor file iki kaya file lawas, kita bisa maca, mbusak lan nyalin.

Ayo ndeleng ukuran file:

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

Ukuran berkas 19923457. Coba mbusak berkas kasebut:

[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

Kaya sing sampeyan ngerteni, ukuran file mung mundhak lan batang kita ora bisa digunakake. Ayo ndeleng dokumentasi panggilan sistem mbukak. Yen kita nggunakake gendΓ©ra O_APPEND nalika mbukak file, banjur saben nulis, sistem operasi mriksa ukuran file lan nulis data menyang mburi banget file, lan nindakake iki atomically. Iki ngidini sawetara utas utawa proses kanggo nulis menyang file sing padha. Nanging ing kode kita ora nggunakake gendera iki. Kita bisa ndeleng ukuran file sing beda ing lsof sawise trunk mung yen kita mbukak file kanggo nulis tambahan, sing tegese ing kode kita

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

kita kudu sijine

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

Priksa nganggo gendera "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

lan nganggo gendΓ©ra "a".

[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

Programing proses sing wis mlaku

Asring programer, nalika nggawe lan nyoba program, nggunakake debuggers (contone GDB) utawa macem-macem tingkat logging ing aplikasi. Linux menehi kemampuan kanggo bener nulis lan ngganti program sing wis mlaku, contone, ngganti nilai variabel, nyetel breakpoint, etc., etc.

Bali menyang pitakonan asli babagan papan disk sing ora cukup kanggo nulis file, ayo nyoba simulasi masalah kasebut.

Ayo nggawe file kanggo partisi kita, sing bakal dipasang minangka disk sing kapisah:

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

Ayo nggawe sistem file:

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

Pasang sistem file:

[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

Kita nggawe direktori karo pemilik kita:

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

Ayo mbukak file kanggo nulis mung ing program kita:

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

Bukak

[user@localhost ]$ python openforwrite.py 

Kita ngenteni sawetara detik

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

Dadi, kita duwe masalah sing diterangake ing wiwitan artikel iki. Ruang bebas 0, 100% dikuwasani.

Kita elinga yen miturut kondisi tugas, kita nyoba ngrekam data sing penting banget sing ora bisa ilang. Lan ing wektu sing padha, kita kudu ndandani layanan kasebut tanpa miwiti maneh proses kasebut.

Contone, kita isih duwe ruang disk, nanging ing partisi sing beda, contone ing /home.

Ayo nyoba "reprogram on the fly" kode kita.

Ayo ndeleng PID proses kita, sing wis mangan kabeh ruang disk:

[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

Sambungake menyang proses liwat gdb

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

Ayo ndeleng deskriptor file sing mbukak:

(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

Kita ndeleng informasi babagan deskriptor file nomer 3, sing narik kawigaten kita

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

Tetep wonten ing pikiran apa sistem nelpon Python ndadekake (ndeleng ndhuwur ngendi kita mlayu strace lan nemokake telpon mbukak), nalika ngolah kode kanggo mbukak file, kita nindakake padha dhΓ©wΓ© atas jenenge proses kita, nanging kita kudu O_WRONLY|O_CREAT| Bit O_TRUNC ngganti karo nilai numerik. Kanggo nindakake iki, bukak sumber kernel, contone kene lan katon ing gendera kang tanggung jawab kanggo apa

#define O_WRONLY 00000001
#define O_CREAT 00000100
#define O_TRUNC 00001000

Kita gabungke kabeh nilai dadi siji, entuk 00001101

Kita mbukak telpon saka gdb

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

Dadi entuk deskriptor file anyar kanthi nomer 4 lan file mbukak anyar ing partisi liyane, kita mriksa:

(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

Kita ngelingi conto karo pipa - carane bash ngganti deskriptor file, lan kita wis sinau telpon sistem dup2.

Kita nyoba ngganti deskriptor file siji karo liyane

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

Priksa:

(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

Kita nutup deskriptor file 4, amarga kita ora butuh:

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

Lan metu saka 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

Priksa file anyar:

[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

Kaya sing sampeyan ngerteni, data kasebut ditulis menyang file anyar, ayo priksa sing lawas:

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

Ora ana data sing ilang, aplikasi bisa digunakake, log ditulis menyang lokasi anyar.

Ayo dadi complicate tugas sethitik

Ayo mbayangno manawa data kasebut penting kanggo kita, nanging kita ora duwe ruang disk ing partisi lan ora bisa nyambungake disk.

Apa kita bisa nindakake iku pangalihan data kita nang endi wae, contone kanggo pipe, lan siji pangalihan data saka pipe kanggo jaringan liwat sawetara program, contone netcat.
Kita bisa nggawe pipa jenenge kanthi perintah mkfifo. Bakal nggawe file pseudo ing sistem file sanajan ora ana ruang kosong.

Wiwiti maneh aplikasi lan priksa:

[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

Ora ana ruang disk, nanging kita kasil nggawe pipa jenenge ing kana:

[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

Saiki kita kudu mbungkus kabeh data sing mlebu ing pipa iki menyang server liyane liwat jaringan; netcat sing padha cocok kanggo iki.

Ing server remote-server.example.com kita mbukak

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

Ing server masalah kita diluncurake ing terminal sing kapisah

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

Saiki kabeh data sing rampung ing pipa bakal kanthi otomatis menyang stdin ing netcat, sing bakal dikirim menyang jaringan ing port 7777.

Kabeh sing kudu ditindakake yaiku miwiti nulis data menyang pipa sing jenenge iki.

Kita wis mbukak aplikasi:

[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

Saka kabeh gendera, kita mung butuh O_WRONLY amarga file kasebut wis ana lan ora perlu mbusak

[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

Priksa server remot remote-server.example.com

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

Data teka, kita mriksa server masalah

[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

Data disimpen, masalah wis ditanggulangi.

Aku njupuk kesempatan iki kanggo ngucapake salam marang kanca-kanca saka Degiro.
Rungokake podcast Radio T.

Kabeh apik.

Minangka peer, aku saranake sampeyan mikir babagan apa sing bakal ana ing deskriptor file proses kucing lan turu yen sampeyan nindakake perintah ing ngisor iki:

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

Source: www.habr.com

Add a comment