Pipe និង Redirection
មាតិកា
- Stream ទាំងបី ម្តងទៀត
- បញ្ជូន Output ទៅក្នុង File៖
>និង>> - ការ Redirect Error៖
2> - អាន Input ពី File៖
< - Pipe៖ ភ្ជាប់ Command ដោយប្រើ
| - ប្រអប់ឧបករណ៍៖
grep,wc,sort,uniq,cut - បង្កើត Pipeline មួយជំហានម្តងៗ
- មើលផង រក្សាទុកផង ក្នុងពេលតែមួយ៖
tee - សាកល្បងដោយខ្លួនឯង
រហូតមកដល់ពេលនេះ គ្រប់ command ទាំងអស់បានបង្ហាញលទ្ធផលរបស់វាត្រង់ទៅលើអេក្រង់។ ជំពូកនេះនិយាយអំពីការផ្លាស់ប្តូរកន្លែងដែល output នោះទៅ — ទៅក្នុង file ឬទៅក្នុង command មួយទៀត។ នេះជាគំនិតដែលធ្វើឲ្យ command line មានអានុភាពខ្លាំងជាងអ្វីដែលវាមើលទៅឆ្ងាយណាស់។
cd ~/cli-practice
1. Stream ទាំងបី ម្តងទៀត
នៅក្នុង Input/Output អ្នកបានរៀនថា គ្រប់ process ទាំងអស់ចាប់ផ្តើមជាមួយ standard stream បី៖
| Stream | លេខ | ជាធម្មតាភ្ជាប់ទៅ |
|---|---|---|
| stdin (standard input) | 0 | Keyboard |
| 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. សាកល្បងដោយខ្លួនឯង
- រក្សាទុក output របស់
ls -la ~ទៅក្នុង~/cli-practice/home-listing.txt។ បន្ទាប់មកបន្ថែមកាលបរិច្ឆេទថ្ងៃនេះទៅចុង file ដដែលនោះដោយប្រើ>>។ ពិនិត្យវាដោយប្រើcat។ - រត់
ls notes nothereហើយបញ្ជូន output ធម្មតាទៅok.txtនិង error ទៅerr.txt។ មើលខាងក្នុង file ទាំងពីរ។ - ដោយប្រើ
grepបង្ហាញគ្រប់ request ទាំងអស់នៅក្នុងnotes/access.logដែលជាGET។ បន្ទាប់មករាប់ពួកវាដោយប្រើ-c(អ្នកគួរតែទទួលបាន 8)។ - បង្កើត pipeline មួយដែលរាប់ថាតើមាន request ប៉ុន្មានដែលទទួលបាន status code នីមួយៗ។ បង្កើតវាមួយជំហានម្តងៗ។
- បង្កើត file ឈ្មោះមួយដែលមានឈ្មោះស្ទួនដោយប្រើ
printfឧទាហរណ៍printf '%s\n' Dara Sokha Dara Vanna Sokha Dara > names.txt។ រកមើលថាឈ្មោះណាលេចឡើងញឹកញាប់ជាងគេ។ - ប្រើ
history | grepដើម្បីរកគ្រប់ commandcdទាំងអស់ដែលអ្នកបានរត់ក្នុងស៊េរីនេះ។
ឥឡូវនេះ អ្នកអាចផ្សំ command ទាំងឡាយឲ្យក្លាយជាឧបករណ៍ផ្ទាល់ខ្លួនរបស់អ្នកបានហើយ។ បន្ទាប់ តោះយក grep មកប្រើលើ folder ទាំងមូល ហើយរៀនពីរបៀបរក file ណាមួយ នៅទីណាក៏ដោយ។
ទិញកាហ្វេជូនខ្ញុំ
ចូលចិត្តមេរៀននេះមែនទេ? សូមពិចារណាទិញកាហ្វេជូនខ្ញុំមួយកែវ ដើម្បីគាំទ្រការបង្កើតមាតិកាឥតគិតថ្លៃបន្ថែមទៀត!