በሊኑክስ ውስጥ የፋይል ገላጭ ከምሳሌዎች ጋር

አንድ ጊዜ በቃለ መጠይቅ ወቅት ዲስኩ ባዶ ቦታ በመጥፋቱ ምክንያት የማይሰራ አገልግሎት ቢያገኙት ምን ታደርጋላችሁ?

እርግጥ ነው፣ በዚህ ቦታ የተያዘውን ለማየት እና ከተቻለ ቦታውን እንደማጸዳው መለስኩለት።
ከዚያም ቃለ-መጠይቅ አድራጊው በክፋዩ ላይ ምንም ነፃ ቦታ ከሌለስ, ነገር ግን ሁሉንም ቦታ የሚይዙ ፋይሎችን ካላዩስ?

ለዚህም ሁል ጊዜ ክፍት የፋይል ገላጭዎችን ማየት ይችላሉ ፣ ለምሳሌ በ lsof ትዕዛዝ ፣ እና የትኛው መተግበሪያ ሁሉንም ቦታ እንደወሰደ ይረዱ እና ከዚያ እንደ ሁኔታው ​​​​መረጃው አስፈላጊ ከሆነ ላይ በመመስረት እርምጃ መውሰድ ይችላሉ አልኩ ። .

ቃለ-መጠይቅ አድራጊው በመጨረሻው ቃል ላይ አቋረጠኝ, ወደ ጥያቄው ጨምሯል: "መረጃው አያስፈልገንም እንበል, የስህተት ምዝግብ ማስታወሻ ብቻ ነው, ነገር ግን አፕሊኬሽኑ አይሰራም ምክንያቱም ማረም መጻፍ አይችልም"?

“እሺ፣ በመተግበሪያ ውቅረት ውስጥ ማረም ማጥፋት እና እንደገና ማስጀመር እንችላለን” ብዬ መለስኩለት።
ቃለ-መጠይቁ አድራጊው ተቃወመ፡- “አይ፣ አፕሊኬሽኑን እንደገና ማስጀመር አንችልም፣ አሁንም አስፈላጊ መረጃ በማህደረ ትውስታ ውስጥ ተከማችቷል፣ እና አስፈላጊ ደንበኞች ከራሱ አገልግሎት ጋር የተገናኙ ናቸው፣ ይህም እንደገና እንዲገናኝ ማስገደድ አንችልም።

“እሺ” አልኩት፣ “መተግበሪያውን እንደገና ማስጀመር ካልቻልን እና ውሂቡ ለእኛ አስፈላጊ ካልሆነ፣ ይህን ክፍት ፋይል በ ls ትእዛዝ ባናየውም በቀላሉ በፋይል ገላጭ በኩል እናጸዳዋለን። በፋይል ስርዓቱ ላይ"

ጠያቂው ተደስቻለሁ፣ ግን አልነበርኩም።

ከዛ ለምንድነው እውቀቴን የሚፈትነው ሰው ለምን ጠለቅ ብሎ አይቆፍርም? ግን ውሂቡ ከሁሉም በኋላ አስፈላጊ ከሆነስ? አንድን ሂደት እንደገና ማስጀመር ካልቻልን እና ሂደቱ ነፃ ቦታ በሌለው ክፋይ ላይ ለፋይል ስርዓቱ ቢጽፍስ? ቀደም ሲል የተፃፈውን ውሂብ ብቻ ሳይሆን ይህ ሂደት የሚጽፈውን ወይም ለመፃፍ የሚሞክርን መረጃ ማጣት ባንችልስ?

ቱዚክ

በስራዬ መጀመሪያ ላይ የተጠቃሚ መረጃን ለማከማቸት የሚያስፈልግ ትንሽ መተግበሪያ ለመፍጠር ሞክሬ ነበር። እና ከዚያ ተጠቃሚውን ከውሂቡ ጋር እንዴት ማዛመድ እችላለሁ ብዬ አሰብኩ። ለምሳሌ, ኢቫኖቭ ኢቫን ኢቫኖቪች አለኝ, እና እሱ የተወሰነ መረጃ አለው, ግን ከእነሱ ጋር እንዴት ጓደኝነት መመሥረት እችላለሁ? "ቱዚክ" የተባለ ውሻ የዚህ የኢቫን እንደሆነ በቀጥታ ልጠቁም እችላለሁ. ግን ስሙን ቢቀይር እና በኢቫን ምትክ ለምሳሌ ኦሊያ ቢሆንስ? ከዚያ የእኛ ኦሊያ ኢቫኖቫና ኢቫኖቫ ውሻ እንደማይኖረው እና የእኛ ቱዚክ አሁንም የሌለው ኢቫን ይሆናል። ለእያንዳንዱ ተጠቃሚ ልዩ መለያ (መታወቂያ) የሰጠው ዳታቤዝ ይህንን ችግር ለመፍታት ረድቷል፣ እና የእኔ ቱዚክ ከዚህ መታወቂያ ጋር የተሳሰረ ነው፣ ይህም በእውነቱ የመለያ ቁጥር ብቻ ነበር። ስለዚህ, የአሴው ባለቤት መታወቂያ ቁጥር 2 ነበረው, እና በተወሰነ ጊዜ ኢቫን በዚህ መታወቂያ ስር ነበር, ከዚያም ኦሊያ በተመሳሳይ መታወቂያ ስር ሆነች. የሰው ልጅ እና የእንስሳት እርባታ ችግር በተግባር ተፈትቷል.

የፋይል ገላጭ

የፋይሉ ችግር እና ከዚህ ፋይል ጋር የሚሰራው ፕሮግራም በግምት ልክ እንደ ውሻ እና ሰው ተመሳሳይ ነው። ኢቫን.ትክስት የሚባል ፋይል ከፍቼ ቱዚክ የሚለውን ቃል መፃፍ ጀመርኩ እንበል ነገር ግን በፋይሉ ውስጥ የመጀመሪያውን ፊደል “t” ለመፃፍ ብቻ የቻልኩት ይህ ፋይል በአንድ ሰው ለምሳሌ ወደ olya.txt ተቀይሯል። ነገር ግን ፋይሉ አንድ አይነት ነው, እና አሁንም የእኔን አሴን በእሱ ውስጥ መቅዳት እፈልጋለሁ. ፋይል በስርዓት ጥሪ በተከፈተ ቁጥር ክፍት በማንኛውም የፕሮግራም አወጣጥ ቋንቋ ወደ ፋይል የሚጠቁመኝ ልዩ መታወቂያ ይደርሰኛል፣ ይህ መታወቂያ የፋይል ገላጭ ነው። እና በዚህ ፋይል ቀጥሎ ምን እና ማን እንደሚሰራ ምንም ችግር የለውም ፣ ሊሰረዝ ይችላል ፣ ስሙ ሊቀየር ይችላል ፣ ባለቤቱ ሊቀየር ይችላል ፣ ወይም የማንበብ እና የመፃፍ መብቶች ሊነጠቁ ይችላሉ ፣ አሁንም መዳረሻ ይኖረኛል ። ወደ እሱ, ምክንያቱም ፋይሉን በሚከፍትበት ጊዜ የማንበብ እና / ወይም የመጻፍ መብት ነበረኝ እና ከእሱ ጋር መስራት ጀመርኩ, ይህም ማለት መቀጠል አለብኝ ማለት ነው.

በሊኑክስ ውስጥ፣ የሊቢክ ቤተ-መጽሐፍት ለእያንዳንዱ አሂድ መተግበሪያ (ሂደት) 3 ገላጭ ፋይሎችን ይከፍታል፣ ቁጥር 0,1,2፣XNUMX፣XNUMX። ተጨማሪ መረጃ በአገናኞች ላይ ሊገኝ ይችላል ሰው ስቴዲዮ и ሰው stdout

  • የፋይል ገላጭ 0 STDIN ይባላል እና ከመተግበሪያ ግቤት ጋር የተያያዘ ነው
  • ፋይል ገላጭ 1 STDOUT ይባላል እና እንደ የህትመት ትዕዛዞች ያሉ መረጃዎችን ለማውጣት መተግበሪያዎች ይጠቀማሉ
  • የፋይል ገላጭ 2 STDERR ይባላል እና በመተግበሪያዎች የስህተት መልዕክቶችን ለማውጣት ያገለግላል።

በፕሮግራምዎ ውስጥ ለማንበብ ወይም ለመፃፍ ማንኛውንም ፋይል ከከፈቱ ምናልባት የመጀመሪያውን ነፃ መታወቂያ ያገኛሉ እና ቁጥር 3 ይሆናል።

ፒአይዲውን ካወቁ የፋይል ገላጭ ዝርዝር ለማንኛውም ሂደት ሊታይ ይችላል።

ለምሳሌ የባሽ ኮንሶሉን እንከፍት እና የሂደታችንን PID እንይ

[user@localhost ]$ echo $$
15771

በሁለተኛው ኮንሶል ውስጥ እንሩጥ

[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

ለዚህ ጽሁፍ ዓላማ የፋይል ገላጭ ቁጥር 255ን በደህና ችላ ማለት ትችላላችሁ፤ ለፍላጎቱ የተከፈተው በባሽ በራሱ እንጂ በተገናኘው ቤተ-መጽሐፍት አይደለም።

አሁን ሁሉም 3 ገላጭ ፋይሎች ከይስሙላ ተርሚናል መሳሪያ ጋር ተያይዘዋል /dev/pts, ነገር ግን አሁንም ልንጠቀምባቸው እንችላለን, ለምሳሌ, በሁለተኛው ኮንሶል ውስጥ ማስኬድ

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

እና በመጀመሪያው ኮንሶል ውስጥ እናያለን

[user@localhost ]$ hello world

ማዞር እና ቧንቧ

እነዚህን 3 ገላጭ ፋይሎች በማንኛውም ሂደት ውስጥ በቀላሉ መሻር ይችላሉ፣ ባሽን ጨምሮ፣ ለምሳሌ ሁለት ሂደቶችን በሚያገናኝ ቱቦ፣ ይመልከቱ

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

ይህንን ትዕዛዝ እራስዎ ማሄድ ይችላሉ strace -f እና ከውስጥ ምን እየተካሄደ እንዳለ ይመልከቱ, ግን በአጭሩ እነግርዎታለሁ.

የእኛ የወላጅ ባሽ ሂደት በፒአይዲ 15771 ትዕዛዛችንን ይተነትናል እና ምን ያህል ትዕዛዞችን ማስኬድ እንደምንፈልግ በትክክል ይገነዘባል ፣ በእኛ ሁኔታ ሁለቱ አሉ-ድመት እና እንቅልፍ። ባሽ ሁለት የሕፃን ሂደቶችን መፍጠር እንደሚያስፈልገው ያውቃል, እና ወደ አንድ ቧንቧ ያዋህዱ. በአጠቃላይ, bash 2 የልጅ ሂደቶች እና አንድ ቧንቧ ያስፈልገዋል.

Bash የልጆች ሂደቶችን ከመፍጠሩ በፊት የስርዓት ጥሪን ያካሂዳል ቱቦ እና አዲስ የፋይል ገላጭዎችን በጊዜያዊ ቧንቧ ቋት ላይ ይቀበላል፣ ነገር ግን ይህ ቋት የሁለቱን ልጆቻችንን ሂደቶች ገና አላገናኘም።

ለወላጅ ሂደት ፣ ቀድሞውኑ ቧንቧ ያለ ይመስላል ፣ ግን እስካሁን ምንም የሕፃን ሂደቶች የሉም።

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

ከዚያ የስርዓት ጥሪውን ይጠቀሙ ፊደል bash ሁለት የሕፃን ሂደቶችን ይፈጥራል ፣ እና የእኛ ሶስት ሂደቶች ይህንን ይመስላል።

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

ክሎኑ ሂደቱን ከሁሉም የፋይል ገላጭዎች ጋር እንደሚዘጋው አይርሱ, ስለዚህ በወላጅ ሂደት እና በልጁ ላይ አንድ አይነት ይሆናሉ. በ PID 15771 የወላጅ ሂደት ሥራ የልጁን ሂደቶች መከታተል ነው, ስለዚህ ከልጆች ምላሽ ብቻ ይጠብቃል.

ስለዚህ, ቧንቧ አያስፈልገውም, እና የፋይል ገላጭዎችን በቁጥር 3 እና 4 ይዘጋል.

በ PID 9004 የመጀመሪያ ልጅ ባሽ ሂደት ፣ የስርዓቱ ጥሪ dup2የኛን የSTDOUT ፋይል ገላጭ ቁጥር 1 ወደ ፓይፕ የሚያመለክት የፋይል ገላጭ ይለውጣል፣ በእኛ ሁኔታ ቁጥር 3 ነው። ስለዚህ የመጀመሪያው ልጅ በPID 9004 ለ STDOUT የፃፈው ነገር ሁሉ በቀጥታ ወደ ቧንቧ ቋት ውስጥ ይሆናል።

በሁለተኛው የህፃናት ሂደት በPID 9005, bash dup2 ን በመጠቀም የፋይል ገላጭውን STDIN ቁጥር 0 ለመቀየር አሁን ሁለተኛ ባሽ ከ PID 9005 ጋር የሚያነበው ነገር ሁሉ ከቧንቧው ላይ ይነበባል.

ከዚህ በኋላ የፋይል ገላጭዎች ቁጥር 3 እና 4 እንዲሁ በልጆች ሂደቶች ውስጥ ተዘግተዋል, ምክንያቱም ከእንግዲህ ጥቅም ላይ አይውሉም.

ሆን ብዬ የፋይል ገላጭ 255ን ችላ እላለሁ፤ ለውስጣዊ ዓላማዎች በባሽ በራሱ ጥቅም ላይ ይውላል እና በልጆች ሂደቶች ውስጥም ይዘጋል።

በመቀጠል፣ በPID 9004 የመጀመሪያ ልጅ ሂደት፣ bash የስርዓት ጥሪን መጠቀም ይጀምራል exec በትዕዛዝ መስመሩ ላይ የገለጽነው ሊተገበር የሚችል ፋይል በእኛ ሁኔታ /usr/bin/cat ነው።

በሁለተኛው የህፃናት ሂደት በPID 9005፣ bash የገለፅነውን ሁለተኛ ተፈፃሚ ያደርጋል፣ በእኛ ሁኔታ /usr/bin/sleep።

ክፍት ጥሪ በተደረገበት ጊዜ በO_CLOEXEC ባንዲራ ካልተከፈቱ በስተቀር የኤክሰክ ሲስተም ጥሪ የፋይል እጀታዎችን አይዘጋም። በእኛ ሁኔታ, ሊተገበሩ የሚችሉ ፋይሎችን ካስጀመርን በኋላ, ሁሉም የአሁኑ የፋይል ገላጭዎች ይቀመጣሉ.

ኮንሶሉን ይመልከቱ፡-

[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

እንደሚመለከቱት, በሁለቱም ሂደቶች ውስጥ የእኛ የቧንቧ ልዩ ቁጥር አንድ ነው. ስለዚህ ከአንድ ወላጅ ጋር በሁለት የተለያዩ ሂደቶች መካከል ግንኙነት አለን.

ባሽ የሚጠቀመውን የስርዓት ጥሪ ለማያውቁ፣ ትእዛዞቹን በስትሬስ በኩል እንዲያሄዱ እና ከውስጥ የሚሆነውን እንዲመለከቱ በጣም እመክራለሁ። ለምሳሌ እንደዚህ፡-

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

ወደ ችግራችን እንመለስ የዲስክ ቦታ እያለቀ እና ሂደቱን እንደገና ሳንጀምር መረጃን ለማስቀመጥ መሞከር። በግምት 1 ሜጋባይት በሰከንድ ወደ ዲስክ የሚጽፍ ትንሽ ፕሮግራም እንፃፍ። ከዚህም በላይ በሆነ ምክንያት በዲስክ ላይ መረጃ መፃፍ ካልቻልን በቀላሉ ይህንን ችላ እንላለን እና ውሂቡን በአንድ ሰከንድ ውስጥ እንደገና ለመጻፍ እንሞክራለን. እኔ Python እየተጠቀምኩበት ባለው ምሳሌ ውስጥ ማንኛውንም ሌላ የፕሮግራሚንግ ቋንቋ መጠቀም ይችላሉ።

[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

ፕሮግራሙን እናካሂድ እና የፋይል ገላጭዎችን እንይ

[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

እንደሚመለከቱት, የእኛ 3 መደበኛ ፋይል ገላጭ እና አንድ ተጨማሪ የከፈትን አሉን. የፋይሉን መጠን እንፈትሽ፡-

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

ውሂቡ በመጻፍ ላይ ነው፣ በፋይሉ ላይ ያሉትን ፈቃዶች ለመቀየር እንሞክራለን፡-

[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

ተጠቃሚው ወደ ፋይሉ የመፃፍ ፍቃድ ባይኖረውም ውሂቡ አሁንም እየተፃፈ መሆኑን እናያለን። እሱን ለማስወገድ እንሞክር፡-

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

መረጃው የት ነው የተፃፈው? እና በጭራሽ የተጻፉ ናቸው? እኛ እንፈትሻለን፡-

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

አዎ፣ የእኛ ፋይል ገላጭ አሁንም አለ እና ይህን ፋይል ገላጭ እንደ አሮጌው ፋይል ልንይዘው እንችላለን፣ እናነባለን፣ ልናጸዳው እና መቅዳት እንችላለን።

የፋይሉን መጠን እንይ፡-

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

የፋይሉ መጠን 19923457 ነው። ፋይሉን ለማጥራት እንሞክር፡-

[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

እንደሚመለከቱት, የፋይሉ መጠን እየጨመረ ብቻ ነው እና የእኛ ግንድ አልሰራም. የስርዓት ጥሪ ሰነዶችን እንመልከት ክፍት. ፋይል ስንከፍት የO_APPEND ባንዲራ ከተጠቀምን በእያንዳንዱ ጽሁፍ ኦፕሬቲንግ ሲስተሙ የፋይሉን መጠን ይፈትሻል እና እስከ ፋይሉ መጨረሻ ድረስ ያለውን መረጃ ይጽፋል እና ይህን በአቶሚካል ያደርገዋል። ይህ በርካታ ክሮች ወይም ሂደቶች ወደ ተመሳሳይ ፋይል እንዲጽፉ ያስችላቸዋል። በእኛ ኮድ ግን ይህንን ባንዲራ አንጠቀምም። ከግንድ በኋላ በlsof ውስጥ የተለየ የፋይል መጠን ማየት የምንችለው ፋይሉን ለተጨማሪ ጽሑፍ ከከፈትን ብቻ ነው፣ ይህ ማለት በምትኩ በኮዳችን ውስጥ ማለት ነው።

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

ማስቀመጥ አለብን

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

በ"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

እና ከ "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

ቀድሞውንም የሚሄድ ሂደትን ማቀድ

ብዙ ጊዜ ፕሮግራመሮች ፕሮግራሞችን ሲፈጥሩ እና ሲሞክሩ አራሚዎችን (ለምሳሌ GDB) ወይም የተለያዩ የመግቢያ ደረጃዎችን ይጠቀማሉ። ሊኑክስ ቀድሞውኑ እየሰራ ያለውን ፕሮግራም የመፃፍ እና የመቀየር ችሎታ ይሰጣል ፣ ለምሳሌ ፣ የተለዋዋጮችን እሴቶችን መለወጥ ፣ መግቻ ነጥብ ማዘጋጀት ፣ ወዘተ ፣ ወዘተ.

ፋይል ለመጻፍ በቂ የዲስክ ቦታ ስለሌለው ወደ ዋናው ጥያቄ ስንመለስ፣ ችግሩን ለመምሰል እንሞክር።

እንደ የተለየ ዲስክ የምንጭነውን ለክፍላችን ፋይል እንፍጠር።

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

የፋይል ስርዓት እንፍጠር፡-

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

የፋይል ስርዓቱን ይጫኑ;

[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

ከባለቤታችን ጋር ማውጫ እንፈጥራለን፡-

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

በፕሮግራማችን ውስጥ ብቻ ለመፃፍ ፋይሉን እንክፈተው፡-

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

አስጀምር

[user@localhost ]$ python openforwrite.py 

ጥቂት ሰከንዶች እንጠብቃለን።

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

ስለዚህ, በዚህ ጽሑፍ መጀመሪያ ላይ የተገለጸው ችግር አለብን. ነፃ ቦታ 0, 100% ተይዟል.

እንደ ሥራው ሁኔታ, ሊጠፉ የማይችሉ በጣም አስፈላጊ መረጃዎችን ለመመዝገብ እየሞከርን መሆኑን እናስታውሳለን. እና በተመሳሳይ ጊዜ ሂደቱን እንደገና ሳይጀምሩ አገልግሎቱን ማስተካከል አለብን.

አሁንም የዲስክ ቦታ አለን እንበል፣ ግን በተለየ ክፍልፍል፣ ለምሳሌ በ/ቤት።

የእኛን ኮድ "በዝንብ ላይ እንደገና ለማቀድ" እንሞክር.

ሁሉንም የዲስክ ቦታ የበላውን የሂደታችንን PID እንይ፡

[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

በ gdb በኩል ወደ ሂደቱ ይገናኙ

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

ክፍት የፋይል ገላጭዎችን እንመልከት፡-

(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

ስለ ፋይል ገላጭ ቁጥር 3 መረጃን እንመለከታለን, ይህም እኛን ያስደስተናል

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

ፓይዘን የሚባለውን ሲስተም ምን እንደሚሠራ ከግንዛቤ ውስጥ በማስገባት (ከላይ በሩጫ ሮጠን ክፍት ጥሪውን ያገኘንበትን ይመልከቱ)፣ ኮዳችንን ስንሰራ ፋይል ስንከፍት እራሳችንን ሒደታችንን ወክለን ተመሳሳይ ነገር እናደርጋለን፣ ነገር ግን O_WRONLY|O_CREAT| O_TRUNC ቢት በቁጥር እሴት ይተካሉ። ይህንን ለማድረግ ለምሳሌ የከርነል ምንጮችን ይክፈቱ እዚህ እና የትኞቹ ባንዲራዎች ለምን ተጠያቂ እንደሆኑ ተመልከት

O_WRONLY 00000001ን ይግለጹ
# O_CREAT 00000100ን ይግለጹ
# O_TRUNC 00001000 ይግለጹ

ሁሉንም ዋጋዎች ወደ አንድ እናጣምራቸዋለን, 00001101 እናገኛለን

ጥሪያችንን ከ gdb እናሰራለን።

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

ስለዚህ አዲስ የፋይል ገላጭ ቁጥር 4 እና አዲስ ክፍት ፋይል በሌላ ክፍል ላይ አግኝተናል፣ እንፈትሻለን፡-

(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

ምሳሌውን ከፓይፕ ጋር እናስታውሳለን - ባሽ የፋይል ገላጭዎችን እንዴት እንደሚቀይር እና የ dup2 ስርዓት ጥሪን ተምረናል።

አንዱን ፋይል ገላጭ በሌላ ለመተካት እንሞክራለን።

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

እንፈትሻለን

(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

እኛ ስለማንፈልግ ፋይል ገላጭ 4ን እንዘጋዋለን፡-

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

እና ከ 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

አዲሱን ፋይል በመፈተሽ ላይ፡-

[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

እንደሚመለከቱት ውሂቡ ወደ አዲስ ፋይል ተጽፏል፣ አሮጌውን እንፈትሽ፡-

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

ምንም ውሂብ አይጠፋም, አፕሊኬሽኑ ይሰራል, ምዝግብ ማስታወሻዎች ወደ አዲስ ቦታ ይጻፋሉ.

ስራውን ትንሽ እናወሳስበው

ውሂቡ ለእኛ አስፈላጊ እንደሆነ እናስብ, ነገር ግን በየትኛውም ክፍልፋዮች ውስጥ የዲስክ ቦታ የለንም እና ዲስኩን ማገናኘት አንችልም.

ማድረግ የምንችለው ዳታዎቻችንን ወደ አንድ ቦታ በማዞር ለምሳሌ ወደ ቧንቧ ማዞር እና በተራው ደግሞ ዳታውን ከፓይፕ ወደ አውታረመረብ በአንዳንድ ፕሮግራሞች ለምሳሌ በ netcat ማዞር ነው.
በ mkfifo ትዕዛዝ የተሰየመ ቧንቧ መፍጠር እንችላለን. ምንም እንኳን ነጻ ቦታ ባይኖርም በፋይል ስርዓቱ ላይ የውሸት ፋይል ይፈጥራል.

ማመልከቻውን እንደገና ያስጀምሩ እና ያረጋግጡ:

[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

ምንም የዲስክ ቦታ የለም ፣ ግን እዚያ የተሰየመ ቧንቧ በተሳካ ሁኔታ እንፈጥራለን-

[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

አሁን ወደዚህ ፓይፕ የሚገባውን መረጃ ሁሉ በኔትወርኩ ወደሌላ አገልጋይ እንደምንም መጠቅለል አለብን፤ ያው netcat ለዚህ ተስማሚ ነው።

በአገልጋዩ remote-server.example.com ላይ እንሰራለን።

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

ችግር ባለበት አገልጋያችን ላይ በተለየ ተርሚናል ውስጥ እናስጀምራለን።

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

አሁን በፓይፕ ውስጥ የሚያልቅ መረጃ ሁሉ በራስ-ሰር በኔትካት ውስጥ ወደ stdin ይሄዳል ፣ ይህም ወደ አውታረ መረብ በፖርት 7777 ይልካል ።

እኛ ማድረግ ያለብን መረጃዎቻችንን በዚህ በተሰየመ ቱቦ ውስጥ መፃፍ መጀመር ብቻ ነው።

አፕሊኬሽኑን አስቀድመን እየሰራን ነው፡-

[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

ከሁሉም ባንዲራዎች፣ ፋይሉ አስቀድሞ ስላለ እና ማጽዳት ስለማንፈልግ O_WRONLY ብቻ ነው የሚያስፈልገን

[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

የርቀት አገልጋዩን remote-server.example.com በመፈተሽ ላይ

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

ውሂቡ እየመጣ ነው, የችግር አገልጋይን እንፈትሻለን

[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

ውሂቡ ተቀምጧል, ችግሩ ተፈትቷል.

በዚህ አጋጣሚ ከደጊሮ ባልደረቦቼ ጋር ሰላም እላለሁ።
የሬዲዮ-ቲ ፖድካስቶችን ያዳምጡ።

ለሁሉም ጥሩ።

እንደ የቤት ስራ ፣ የሚከተለውን ትዕዛዝ ከሄዱ የድመት እና እንቅልፍ መግለጫዎች በሂደቱ ውስጥ ምን እንደሚሆን እንዲያስቡ እመክርዎታለሁ ።

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

ምንጭ: hab.com

አስተያየት ያክሉ