Pipe និង Redirection

មាតិកា

  1. Stream ទាំងបី ម្តងទៀត
  2. បញ្ជូន Output ទៅក្នុង File៖ > និង >>
  3. ការ Redirect Error៖ 2>
  4. អាន Input ពី File៖ <
  5. Pipe៖ ភ្ជាប់ Command ដោយប្រើ |
  6. ប្រអប់ឧបករណ៍៖ grep, wc, sort, uniq, cut
  7. បង្កើត Pipeline មួយជំហានម្តងៗ
  8. មើលផង រក្សាទុកផង ក្នុងពេលតែមួយ៖ tee
  9. សាកល្បងដោយខ្លួនឯង

រហូតមកដល់ពេលនេះ គ្រប់ command ទាំងអស់បានបង្ហាញលទ្ធផលរបស់វាត្រង់ទៅលើអេក្រង់។ ជំពូកនេះនិយាយអំពីការផ្លាស់ប្តូរកន្លែងដែល output នោះទៅ — ទៅក្នុង file ឬទៅក្នុង command មួយទៀត។ នេះជាគំនិតដែលធ្វើឲ្យ command line មានអានុភាពខ្លាំងជាងអ្វីដែលវាមើលទៅឆ្ងាយណាស់។

cd ~/cli-practice

1. Stream ទាំងបី ម្តងទៀត

នៅក្នុង Input/Output អ្នកបានរៀនថា គ្រប់ process ទាំងអស់ចាប់ផ្តើមជាមួយ standard stream បី៖

Streamលេខជាធម្មតាភ្ជាប់ទៅ
stdin (standard input)0Keyboard
stdout (standard output)1អេក្រង់ terminal
stderr (standard error)2អេក្រង់ terminal

កម្មវិធីដូចជា ls មិនដឹង ហើយក៏មិនខ្វល់ថា output របស់វាទៅដល់ទីណានោះទេ។ វាគ្រាន់តែសរសេរទៅ stdout។ គឺ shell ទេដែលសម្រេចថា stdout ត្រូវភ្ជាប់ទៅកន្លែងណា — ហើយអ្នកអាចប្រាប់ shell ឲ្យភ្ជាប់វាទៅកន្លែងផ្សេង។ Redirection គឺមានតែប៉ុណ្ណឹងឯង។

ហេតុអ្វីបានជាមាន output stream ពីរ? គឺដើម្បីឲ្យ លទ្ធផលធម្មតា និង សារ error អាចញែកចេញពីគ្នាបាន។ នៅលើអេក្រង់ ពួកវាមើលទៅដូចគ្នា ប៉ុន្តែដូចដែលអ្នកនឹងឃើញ អ្នកអាចបញ្ជូនពួកវាទៅកន្លែងផ្សេងគ្នាបាន។

2. បញ្ជូន Output ទៅក្នុង File៖ > និង >>

> បញ្ជូន stdout របស់ command មួយ ទៅក្នុង file ជំនួសឲ្យអេក្រង់៖

ls -l notes > listing.txt

គ្មានអ្វីលេចឡើងលើអេក្រង់ទេ — output បានចូលទៅក្នុង listing.txt។ ពិនិត្យមើលវា៖

cat listing.txt

បើ file នោះមិនទាន់មាន > នឹងបង្កើតវា។ បើវាមានរួចហើយ > នឹងជំនួសអ្វីៗទាំងអស់នៅក្នុងវា ដោយគ្មានការព្រមានឡើយ៖

echo "first" > test.txt
echo "second" > test.txt
cat test.txt
second

first បាត់ហើយ។ ដើម្បី បន្ថែមទៅខាងចុង file វិញ សូមប្រើ >>៖

echo "third" >> test.txt
echo "fourth" >> test.txt
cat test.txt
second
third
fourth

វិធីចងចាំងាយៗ៖ > មានព្រួញមួយ — ចាប់ផ្តើមថ្មី; >> មានព្រួញពីរ — បន្ថែមបន្តទៀត។

វាដំណើរការជាមួយ command ណាក៏ដោយដែលបង្ហាញអ្វីមួយ៖

date > timestamp.txt
history > my-commands.txt
seq 1 100 > hundred.txt

កំហុសបុរាណ៖ កុំ redirect output របស់ command មួយទៅក្នុង file ដដែលដែលវាកំពុងអាន។ sort names.txt > names.txt មិនតម្រៀប file នោះទេ — shell សម្អាត names.txt ឲ្យទទេ មុនពេល sort ចាប់ផ្តើម ដូច្នេះ sort អាន file ទទេមួយ ហើយអ្នកបាត់បង់អ្វីៗទាំងអស់។ សូមសរសេរទៅ file ថ្មីមួយជំនួសវិញ បន្ទាប់មកប្តូរឈ្មោះវាដោយប្រើ mv។

3. ការ Redirect Error៖ 2>

សាកល្បង list folder មួយដែលមាន និង folder មួយទៀតដែលមិនមាន ដោយបញ្ជូន output ទៅក្នុង file៖

ls notes nothere > out.txt
ls: nothere: No such file or directory

Error នៅតែលេចឡើងលើអេក្រង់ ហើយ out.txt មានតែផ្នែកដែលជោគជ័យប៉ុណ្ណោះ។ នោះគឺដោយសារតែ > redirect តែ stdout ប៉ុណ្ណោះ។ Error បានទៅ stderr ដែលនៅតែភ្ជាប់ទៅអេក្រង់។

ដើម្បី redirect stderr សូមដាក់លេខរបស់វា គឺ 2 នៅពីមុខព្រួញ៖

ls notes nothere > out.txt 2> errors.txt

ឥឡូវនេះគ្មានអ្វីលេចឡើងលើអេក្រង់ទេ៖ លទ្ធផលនៅក្នុង out.txt ហើយ error នៅក្នុង errors.txt។ នេះពិតជាមានប្រយោជន៍ — ឧទាហរណ៍ ការរត់ build ដែលចំណាយពេលយូរ ហើយរក្សាទុក error របស់វាដើម្បីអាននៅពេលក្រោយ។

ទម្រង់ពីរទៀតដែលអ្នកនឹងឃើញក្នុង tutorial និង script៖

command > all.txt 2>&1   # stdout AND stderr into the same file
command 2> /dev/null     # throw the errors away

2>&1 មានន័យថា «បញ្ជូន stream 2 ទៅកន្លែងដូចគ្នានឹង stream 1»។ ហើយ /dev/null គឺជា file ពិសេសមួយដែលលេបអ្វីៗទាំងអស់ដែលសរសេរចូលទៅក្នុងវា — ជារន្ធខ្មៅសម្រាប់ output ដែលអ្នកមិនចង់បាន។ សូមប្រើវាដោយប្រុងប្រយ័ត្ន៖ ការលាក់ error ក៏លាក់តម្រុយដែលអ្នកត្រូវការនៅពេលមានអ្វីមួយខុសដែរ។

4. អាន Input ពី File៖ <

ផ្ទុយពី > គឺ < ដែលបញ្ចូល file មួយទៅក្នុង stdin របស់ command៖

wc -l < hundred.txt
100

អ្នកនឹងមិនសូវប្រើ < ញឹកញាប់ដូចផ្សេងទៀតទេ ព្រោះ command ភាគច្រើនអាចបើក file ដោយខ្លួនឯងបាន បើអ្នកគ្រាន់តែផ្តល់ឈ្មោះរបស់វា។ ប្រៀបធៀប៖

wc -l hundred.txt     # 100 hundred.txt
wc -l < hundred.txt   # 100

កំណែទីពីរបង្ហាញតែលេខប៉ុណ្ណោះ ព្រោះ wc មិនដែលដឹងឈ្មោះ file ទេ — វាគ្រាន់តែទទួលខ្លឹមសារតាមរយៈ stdin។

5. Pipe៖ ភ្ជាប់ Command ដោយប្រើ |

នេះជាគំនិតដ៏ធំ។ Pipe | ភ្ជាប់ stdout របស់ command មួយ ដោយផ្ទាល់ទៅ stdin របស់ command បន្ទាប់៖

ls -l /usr/bin | less

ls បង្ហាញបញ្ជីកម្មវិធីរាប់រយនៅក្នុង /usr/bin។ ជំនួសឲ្យការជន់លិចអេក្រង់ output របស់វាហូរត្រង់ចូលទៅក្នុង less ដែលអ្នកអាច scroll មើលវាបាន។ (ចុច q ដើម្បីចេញ។)

អ្នកអាចភ្ជាប់ command ច្រើនប៉ុន្មានក៏បានតាមចិត្ត៖

command1 | command2 | command3

Command នីមួយៗធ្វើ ការងារតូចមួយ ហើយ pipe បញ្ជូនលទ្ធផលបន្តទៅមុខ — ដូចជាកម្មករនៅលើខ្សែសង្វាក់ផលិតកម្ម ឬទឹកហូរតាមបំពង់ (pipe) ដែលជាប្រភពនៃឈ្មោះនេះ។ នេះជាគំនិតរចនាមួយក្នុងចំណោមគំនិតចាស់ជាងគេបំផុតរបស់ Unix៖ ឧបករណ៍តូចៗដែលនីមួយៗធ្វើរឿងមួយឲ្យបានល្អ ហើយអាចផ្សំគ្នាបាន។

គ្មាន file បណ្តោះអាសន្នណាមួយត្រូវបានបង្កើតឡើងទេ។ ទិន្នន័យហូរពី process មួយទៅ process បន្ទាប់នៅក្នុង memory ហើយ command ទាំងអស់ក្នុង pipeline ពិតជារត់ ក្នុងពេលតែមួយ — ពិតជាប្រភេទ process ដែលរត់ស្របគ្នា ដែលអ្នកបានជួបក្នុង How Computers Work។

6. ប្រអប់ឧបករណ៍៖ grep, wc, sort, uniq, cut

Pipe ក្លាយជាមានអានុភាពនៅពេលអ្នកស្គាល់ command filter មួយចំនួន — កម្មវិធីដែលអានបន្ទាត់ ធ្វើអ្វីមួយលើពួកវា ហើយបង្ហាញលទ្ធផល។

តោះបង្កើត log របស់ web server តូចមួយដើម្បីហាត់។ printf បង្ហាញ string នីមួយៗដែលនៅក្នុងសញ្ញាសម្រង់ នៅលើបន្ទាត់ផ្ទាល់ខ្លួនរបស់វា៖

printf '%s\n' \
  "GET /home 200" \
  "GET /about 200" \
  "POST /login 401" \
  "GET /home 200" \
  "GET /products 500" \
  "POST /login 200" \
  "GET /home 200" \
  "GET /products 500" \
  "GET /contact 404" \
  "GET /about 200" > notes/access.log

សញ្ញា \ នៅចុងបន្ទាត់នីមួយៗគ្រាន់តែមានន័យថា «command នេះបន្តនៅបន្ទាត់បន្ទាប់»។ អ្នកអាចចម្លងប្លុកទាំងមូល ហើយបិទភ្ជាប់វាក្នុងពេលតែមួយ។

បន្ទាត់នីមួយៗគឺជា request មួយ៖ method, ទំព័រ និង status code (200 គឺ OK, 404 គឺរកមិនឃើញ, 500 គឺ error របស់ server)។

grep — រក្សាទុកតែបន្ទាត់ដែលត្រូវគ្នា

grep "500" notes/access.log
GET /products 500
GET /products 500

Option ដែលមានប្រយោជន៍៖

Optionអត្ថន័យ
-iមិនខ្វល់ពីអក្សរធំ/អក្សរតូច
-vបញ្ច្រាស៖ រក្សាទុកបន្ទាត់ដែល មិន ត្រូវគ្នា
-cគ្រាន់តែរាប់បន្ទាត់ដែលត្រូវគ្នា
-nបង្ហាញលេខបន្ទាត់
grep -v " 200" notes/access.log   # every request that wasn't OK
grep -c "POST" notes/access.log   # how many POST requests: 2

wc — រាប់

wc (word count) រាប់បន្ទាត់ ពាក្យ និងតួអក្សរ។ អ្នកនឹងប្រើ -l សម្រាប់បន្ទាត់ច្រើនជាងគេ៖

wc -l notes/access.log
10 notes/access.log

sort — តម្រៀបបន្ទាត់តាមលំដាប់

sort notes/access.log        # alphabetical
sort -r notes/access.log     # reversed
seq 1 20 | sort -n -r        # numbers, largest first

-n តម្រៀប តាមតម្លៃលេខ។ បើគ្មានវាទេ sort ប្រៀបធៀបជាអក្សរ ដូច្នេះ 10 មកមុន 9 (ព្រោះ 1 មកមុន 9)។

uniq — លុបបន្ទាត់ដែលស្ទួន

uniq បង្រួមបន្ទាត់ដែលស្ទួនគ្នាឲ្យនៅសល់តែមួយ។ បន្ថែម -c ដើម្បី រាប់ ថាបន្ទាត់នីមួយៗលេចឡើងប៉ុន្មានដង។ ប៉ុន្តែមានល្បិចមួយ៖ វាកត់សម្គាល់តែបន្ទាត់ស្ទួនដែល នៅជាប់គ្នា ប៉ុណ្ណោះ ដូច្នេះអ្នកស្ទើរតែតែងតែ sort ជាមុនសិន។

cut — ជ្រើសយក column មួយ

cut ទាញយកផ្នែកមួយនៃបន្ទាត់នីមួយៗ។ -d " " ប្រាប់ថា column ត្រូវបានបំបែកដោយដកឃ្លា ហើយ -f 2 ជ្រើសយក column ទីពីរ៖

cut -d " " -f 2 notes/access.log
/home
/about
/login
...

7. បង្កើត Pipeline មួយជំហានម្តងៗ

ឥឡូវតោះឆ្លើយសំណួរពិតមួយ៖ តើទំព័រណាខ្លះដែលត្រូវបានចូលមើលច្រើនជាងគេ?

ល្បិចក្នុងការសរសេរ pipeline គឺ បង្កើតវាមួយជំហានម្តងៗ ដោយរត់ command បន្ទាប់ពីបន្ថែម | ថ្មីនីមួយៗ ដើម្បីមើលថាតើមានអ្វីចេញមក។

ជំហានទី 1 — យកតែឈ្មោះទំព័រ៖

cut -d " " -f 2 notes/access.log

ជំហានទី 2 — តម្រៀបពួកវា ដើម្បីឲ្យទំព័រដូចគ្នានៅជាប់គ្នា៖

cut -d " " -f 2 notes/access.log | sort

ជំហានទី 3 — រាប់ក្រុមនីមួយៗ៖

cut -d " " -f 2 notes/access.log | sort | uniq -c

ជំហានទី 4 — តម្រៀបតាមចំនួននោះ ពីធំបំផុតមុន៖

cut -d " " -f 2 notes/access.log | sort | uniq -c | sort -rn
   3 /home
   2 /products
   2 /login
   2 /about
   1 /contact

ជំហានទី 5 — រក្សាទុកតែបីខាងលើ៖

cut -d " " -f 2 notes/access.log | sort | uniq -c | sort -rn | head -n 3

Command តូចៗចំនួនប្រាំ ដែលគ្មានមួយណាដឹងអ្វីអំពី web log សោះ ផ្សំគ្នាក្លាយជាឧបករណ៍វិភាគទិន្នន័យតូចមួយ។ ប្តូរ -f 2 ទៅជា -f 3 នោះ pipeline ដដែលនឹងរាប់ status code ជំនួសវិញ។ ចង្អុលវាទៅ log ពិតដែលមានមួយលានបន្ទាត់ ហើយវានៅតែបញ្ចប់ក្នុងរយៈពេលមួយ ឬពីរវិនាទី។

Pipeline មួយចំនួនទៀតដែលអ្នកនឹងប្រើពិតប្រាកដ៖

history | grep "git"           # find that git command you ran yesterday
ls -l | grep ".txt"            # only .txt entries in a long listing
cat notes/*.txt | wc -l        # total lines across all your notes

អំពី cat file | grep៖ អ្នកនឹងឃើញជាញឹកញាប់នូវ cat access.log | grep 500។ វាដំណើរការ ប៉ុន្តែ grep 500 access.log ធ្វើរឿងដូចគ្នា ដោយប្រើ process តិចជាងមួយ។ ទាំងពីរសុទ្ធតែមិនអីទេ ខណៈពេលដែលអ្នកកំពុងរៀន។

8. មើលផង រក្សាទុកផង ក្នុងពេលតែមួយ៖ tee

ជាមួយ > output ចូលទៅក្នុង file ហើយអ្នកមិនឃើញវាទេ។ ពេលខ្លះអ្នកចង់បាន ទាំងពីរ។ tee អាន stdin សរសេរវាទៅក្នុង file ហើយ បញ្ជូនវាបន្តទៅ stdout ផងដែរ — ដូចជាតំណបំពង់រាងអក្សរ T៖

grep -v " 200" notes/access.log | tee notes/problems.txt

បន្ទាត់ដែលមានបញ្ហាលេចឡើងលើអេក្រង់ ហើយត្រូវបានរក្សាទុកក្នុង problems.txt។ បន្ថែម -a ដើម្បីបន្ថែមទៅខាងចុង ជំនួសឲ្យការជំនួស ដូចគ្នានឹង >> ដែរ។

9. សាកល្បងដោយខ្លួនឯង

  1. រក្សាទុក output របស់ ls -la ~ ទៅក្នុង ~/cli-practice/home-listing.txt។ បន្ទាប់មកបន្ថែមកាលបរិច្ឆេទថ្ងៃនេះទៅចុង file ដដែលនោះដោយប្រើ >>។ ពិនិត្យវាដោយប្រើ cat។
  2. រត់ ls notes nothere ហើយបញ្ជូន output ធម្មតាទៅ ok.txt និង error ទៅ err.txt។ មើលខាងក្នុង file ទាំងពីរ។
  3. ដោយប្រើ grep បង្ហាញគ្រប់ request ទាំងអស់នៅក្នុង notes/access.log ដែលជា GET។ បន្ទាប់មករាប់ពួកវាដោយប្រើ -c (អ្នកគួរតែទទួលបាន 8)។
  4. បង្កើត pipeline មួយដែលរាប់ថាតើមាន request ប៉ុន្មានដែលទទួលបាន status code នីមួយៗ។ បង្កើតវាមួយជំហានម្តងៗ។
  5. បង្កើត file ឈ្មោះមួយដែលមានឈ្មោះស្ទួនដោយប្រើ printf ឧទាហរណ៍ printf '%s\n' Dara Sokha Dara Vanna Sokha Dara > names.txt។ រកមើលថាឈ្មោះណាលេចឡើងញឹកញាប់ជាងគេ។
  6. ប្រើ history | grep ដើម្បីរកគ្រប់ command cd ទាំងអស់ដែលអ្នកបានរត់ក្នុងស៊េរីនេះ។

ឥឡូវនេះ អ្នកអាចផ្សំ command ទាំងឡាយឲ្យក្លាយជាឧបករណ៍ផ្ទាល់ខ្លួនរបស់អ្នកបានហើយ។ បន្ទាប់ តោះយក grep មកប្រើលើ folder ទាំងមូល ហើយរៀនពីរបៀបរក file ណាមួយ នៅទីណាក៏ដោយ។

ទិញកាហ្វេជូនខ្ញុំ

ចូលចិត្តមេរៀននេះមែនទេ? សូមពិចារណាទិញកាហ្វេជូនខ្ញុំមួយកែវ ដើម្បីគាំទ្រការបង្កើតមាតិកាឥតគិតថ្លៃបន្ថែមទៀត!