Process ពី Terminal

មាតិកា

  1. គ្រប់ Command សុទ្ធតែជា Process
  2. មើលអ្វីដែលកំពុងរត់៖ ps
  3. ការមើលផ្ទាល់៖ top និង htop
  4. បញ្ឈប់ Process៖ Ctrl + C និង kill
  5. Foreground និង Background
  6. Exit Code៖ តើវាដំណើរការទេ?
  7. «Port 3000 ត្រូវបានប្រើរួចហើយ»
  8. សាកល្បងដោយខ្លួនឯង

1. គ្រប់ Command សុទ្ធតែជា Process

នៅក្នុង Process អ្នកបានរៀនថា process គឺជាកម្មវិធីដែលកំពុងរត់ ដែលមាន PID (process ID) ផ្ទាល់ខ្លួន memory ផ្ទាល់ខ្លួន និង parent ដែលបានចាប់ផ្តើមវា។ អ្នកបានមើលពួកវានៅក្នុង Task Manager ឬ Activity Monitor។

គ្រប់ command ទាំងអស់ដែលអ្នកបានវាយក្នុងស៊េរីនេះ សុទ្ធតែជា process។ នៅពេលអ្នករត់ ls shell ចាប់ផ្តើម child process មួយ ls ធ្វើការងាររបស់វាក្នុងរយៈពេលពីរបី millisecond ហើយចេញ។ អ្នកមិនដែលកត់សម្គាល់ទេ ព្រោះវាចប់ស្ទើរតែភ្លាមៗ។

ប៉ុន្តែកម្មវិធីជាច្រើនដែលអ្នកនឹងរត់ក្នុងនាមជាអ្នកអភិវឌ្ឍន៍ មិន បញ្ចប់ដោយខ្លួនឯងទេ៖

  • npm run dev ចាប់ផ្តើម development server មួយដែលរត់រហូតដល់អ្នកបញ្ឈប់វា។
  • tail -f (ជំពូកទី 5) តាមដាន file មួយជារៀងរហូត។
  • Database ឬ Docker container មួយរត់អស់ច្រើនថ្ងៃ។

សម្រាប់កម្មវិធីទាំងនេះ អ្នកត្រូវដឹងពីរបៀបមើលអ្វីដែលកំពុងរត់ បញ្ឈប់វា និងរត់វាដោយមិនរាំងស្ទះ terminal របស់អ្នក។ ដើម្បីមានអ្វីមួយសម្រាប់ហាត់ យើងនឹងប្រើ sleep ដែលមិនធ្វើអ្វីទាល់តែសោះ ក្នុងរយៈពេលប៉ុន្មានវិនាទីដែលអ្នកផ្តល់ឲ្យវា។ ដូចសព្វដង សូមធ្វើការពី folder ហាត់របស់អ្នក៖

cd ~/cli-practice
sleep 5

ក្នុងរយៈពេលប្រាំវិនាទី prompt មិនត្រឡប់មកវិញទេ។ Shell កំពុងរង់ចាំ process sleep ឲ្យបញ្ចប់។

2. មើលអ្វីដែលកំពុងរត់៖ ps

ps (process status) បង្ហាញបញ្ជី process។ ពេលប្រើតែឯង វាបង្ហាញតែ process ដែលបានចាប់ផ្តើមពី terminal នេះ ប៉ុណ្ណោះ៖

ps
  PID TTY           TIME CMD
 1934 ttys001    0:00.66 -zsh

នោះគឺជា shell របស់អ្នកខ្លួនឯង។ ដើម្បីមើល គ្រប់ process ទាំងអស់នៅលើកុំព្យូទ័រ ពីគ្រប់អ្នកប្រើប្រាស់ សូមបន្ថែម aux៖

ps aux

នោះមានរាប់រយបន្ទាត់។ Column ដែលអ្នកគួរយកចិត្តទុកដាក់៖

Columnអត្ថន័យ
USERអ្នកណាជាម្ចាស់ process
PIDProcess ID របស់វា
%CPU / %MEMចំនួន CPU និង memory ដែលវាកំពុងប្រើនៅពេលនេះ
COMMANDCommand ដែលបានចាប់ផ្តើមវា

អ្នកស្ទើរតែមិនដែលអាន ps aux ទាំងមូលទេ។ ផ្ទុយទៅវិញ សូម pipe វាទៅក្នុង grep (ជំពូកទី 6) ដើម្បីរក process ដែលអ្នកកំពុងស្វែងរក៖

ps aux | grep node

លទ្ធផលជាញឹកញាប់មានបន្ទាត់បន្ថែមមួយ — គឺ command grep node ខ្លួនឯង ដែលក៏ជា process មួយដែលមាន node នៅក្នុងឈ្មោះរបស់វាដែរ។ មិនបាច់ខ្វល់ពីវាទេ។

Git Bash៖ ps របស់វាជាកំណែសាមញ្ញជាង ដែលមិនយល់ aux ហើយបង្ហាញតែ process ផ្ទាល់ខ្លួនរបស់ Git Bash ប៉ុណ្ណោះ។ សូមប្រើ Task Manager ដើម្បីមើលរូបភាពពេញលេញ ឬប្រើ WSL។

3. ការមើលផ្ទាល់៖ top និង htop

ps គឺជារូបថតមួយភ្លែត។ top គឺជា Task Manager កំណែ terminal៖ ជាការមើលផ្ទាល់ដែល refresh រៀងរាល់ពីរបីវិនាទី ដោយមាន process ដែលរវល់បំផុតនៅខាងលើ៖

top

ចុច q ដើម្បីចេញ — key ដូចគ្នានឹង less និង man ដែរ។

អ្នកអភិវឌ្ឍន៍ជាច្រើនចូលចិត្ត htop ដែលជាកំណែងាយស្រួលប្រើជាង មានពណ៌ របារ CPU និងអាចប្រើ mouse បាន។ វាមិនតែងតែត្រូវបានដំឡើងជាស្រេចទេ ប៉ុន្តែងាយស្រួលបន្ថែម៖

sudo apt install htop   # Ubuntu and WSL
brew install htop       # macOS, if you use Homebrew

(sudo និងការដំឡើង software នឹងលេចឡើងក្នុងជំពូកទី 10។)

4. បញ្ឈប់ Process៖ Ctrl + C និង kill

Ctrl + C

អ្នកបានប្រើវាតាំងពីជំពូកទី 2 មកម្ល៉េះ។ ចាប់ផ្តើមអ្វីមួយដែលយូរ៖

sleep 100

ចុច Ctrl + C។ Prompt ត្រឡប់មកវិញភ្លាមៗ។

អ្វីដែលពិតជាកើតឡើងគឺ terminal ផ្ញើ signal មួយ — សារតូចមួយពីប្រព័ន្ធប្រតិបត្តិការ — ទៅកាន់ process ដែលហៅថា SIGINT («interrupt»)។ កម្មវិធីភាគច្រើនឆ្លើយតបដោយការសម្អាត ហើយចេញ។ នោះហើយជារបៀបដែលអ្នកបញ្ឈប់ npm run dev, tail -f និងស្ទើរតែអ្វីៗផ្សេងទៀតដែលកំពុងរត់នៅ foreground។

kill

ចុះបើ process នោះមិននៅពីមុខអ្នក — វាកំពុងរត់នៅក្នុង terminal មួយទៀត ឬនៅផ្ទៃខាងក្រោយ ឬវាគាំង? រក PID របស់វា បន្ទាប់មកប្រើ kill៖

ps aux | grep sleep
kill 12345            # use the real PID from the line above

ទោះបីជាមានឈ្មោះបែបនេះក៏ដោយ kill គ្រាន់តែ ផ្ញើ signal ប៉ុណ្ណោះ។ តាមលំនាំដើម វាផ្ញើ SIGTERM («terminate») ដែលស្នើសុំ process ដោយគួរសមឲ្យបិទខ្លួន។ កម្មវិធីដែលមានឥរិយាបថល្អនឹងរក្សាទុកការងាររបស់វា បិទ file របស់វា ហើយចេញ។

បើ process មួយពិតជាគាំង ហើយមិនអើពើនឹងសំណើនោះ អ្នកអាចផ្ញើ SIGKILL ដោយប្រើ -9៖

kill -9 12345

SIGKILL មិនអាចចាប់ ឬមិនអើពើបានទេ៖ ប្រព័ន្ធប្រតិបត្តិការគ្រាន់តែដក process នោះចេញ។ នោះក៏ជាមូលហេតុដែលវាជា ជម្រើសចុងក្រោយ — កម្មវិធីគ្មានឱកាសសម្អាតទេ ដូច្នេះ file ដែលវាកំពុងសរសេរអាចនៅសល់ពាក់កណ្តាល។ សូមសាកល្បង kill ធម្មតាជាមុនសិនជានិច្ច។

Signalផ្ញើដោយអត្ថន័យ
SIGINTCtrl + C«សូមឈប់» (ពី keyboard)
SIGTERMkill PID«សូមបិទខ្លួន»
SIGKILLkill -9 PID«ឯងត្រូវចេញហើយ» — មិនអាចបដិសេធបាន

អ្នកក៏អាចបញ្ឈប់ process តាមឈ្មោះ ជំនួសឲ្យ PID ដោយប្រើ pkill៖

pkill sleep

សូមប្រុងប្រយ័ត្ន៖ វាបញ្ឈប់ គ្រប់ process ទាំងអស់ដែលមានឈ្មោះនោះ ដែលអ្នកជាម្ចាស់។

5. Foreground និង Background

ជាធម្មតា command មួយរត់នៅ foreground៖ វាកាន់កាប់ terminal របស់អ្នករហូតដល់វាបញ្ចប់ ហើយអ្នកមិនអាចវាយ command ផ្សេងទៀតបានទេ។ បន្ថែម & នៅខាងចុង ដើម្បីរត់វានៅ background ជំនួសវិញ៖

sleep 300 &
[1] 23456

Prompt ត្រឡប់មកវិញភ្លាម។ Shell បង្ហាញ job number ([1]) និង PID។ Process នៅតែបន្តរត់ ខណៈពេលដែលអ្នកបន្តធ្វើការ។

jobs បង្ហាញបញ្ជី background job ដែលបានចាប់ផ្តើមពី terminal នេះ៖

jobs
[1]  + running    sleep 300

អ្នកអាចផ្លាស់ job ទៅមកបាន៖

Commandអ្វីដែលវាធ្វើ
command &ចាប់ផ្តើមនៅ background
Ctrl + Zផ្អាក process នៅ foreground ហើយដាក់វាទៅ background ក្នុងស្ថានភាពឈប់
bgបន្ត job ដែលបានផ្អាក ឲ្យរត់នៅ background
fgនាំ background job មួយត្រឡប់មក foreground វិញ
kill %1បញ្ឈប់ job លេខ 1 (សូមកត់សម្គាល់សញ្ញា %)

សាកល្បងវា៖

sleep 300

ចុច Ctrl + Z — prompt ត្រឡប់មកវិញ ហើយ shell ប្រាប់ថា job នោះត្រូវបាន suspended (ផ្អាក)។ រត់ jobs ដើម្បីមើលវា fg ដើម្បីនាំវាត្រឡប់មកវិញ បន្ទាប់មក Ctrl + C ដើម្បីបញ្ឈប់វាជាស្ថាពរ។

ប្រយ័ត្នជាមួយ Ctrl + Z៖ អ្នកចាប់ផ្តើមដំបូងពេលខ្លះចុចវាដោយគិតថាវាមានន័យថា «undo» ឬ «quit»។ វាគ្រាន់តែ ផ្អាក កម្មវិធីប៉ុណ្ណោះ ដែលនៅតែស្ថិតនៅក្នុង memory — ហើយបើវាជា server វានៅតែកាន់ port របស់វា (សូមមើលផ្នែកទី 7)។ បើ command មួយ «បាត់» ហើយអ្វីៗដំណើរការចម្លែក សូមរត់ jobs។

នៅពេលអ្នក បិទផ្ទាំង terminal process ដែលបានចាប់ផ្តើមពីវាជាធម្មតាក៏ត្រូវបានបញ្ឈប់ដែរ។ នោះហើយជាមូលហេតុដែល server និងឧបករណ៍ដែលរត់យូរ ជាធម្មតាត្រូវបានរត់ដោយ process manager ឬនៅខាងក្នុង Docker ជាជាងពី terminal ដែលនរណាម្នាក់បើកទុក។

6. Exit Code៖ តើវាដំណើរការទេ?

នៅពេល process មួយបញ្ចប់ វាប្រគល់លេខមួយត្រឡប់ទៅ parent របស់វាវិញ ដែលហៅថា exit code (ឬ exit status)។ ច្បាប់គឺសាមញ្ញ៖

  • 0 មានន័យថាជោគជ័យ។
  • លេខផ្សេងពីនេះ មានន័យថាមានអ្វីមួយខុស។ លេខផ្សេងៗគ្នាអាចមានន័យថាបញ្ហាផ្សេងៗគ្នា។

Shell រក្សាទុក exit code របស់ command ចុងក្រោយនៅក្នុង variable ពិសេសមួយគឺ $?៖

ls notes
echo $?
0
ls nothere
echo $?
1

(ls របស់ Linux ត្រឡប់ 2 នៅទីនេះជំនួសវិញ — លេខណាក៏ដោយដែលមិនមែនសូន្យ មានន័យថាបរាជ័យ។)

អ្នកនឹងមិនសូវពិនិត្យ $? ដោយដៃញឹកញាប់ទេ ប៉ុន្តែ exit code គឺជារបៀបដែល អ្វីៗទាំងអស់ សម្រេចថាតើជំហានមួយបានដំណើរការឬអត់៖ shell script (ជំពូកទី 11) Git hook CI pipeline ដែលរត់ test របស់អ្នកនៅលើ GitHub និង Docker health check។ នៅពេល test runner «ធ្វើឲ្យ build បរាជ័យ» វាធ្វើដូច្នោះដោយការចេញជាមួយ code ដែលមិនមែនសូន្យ។

អ្នកក៏អាចប្រើពួកវាដើម្បីភ្ជាប់ command ជាខ្សែបានដែរ។ && រត់ command ទីពីរ លុះត្រាតែ command ទីមួយជោគជ័យ៖

mkdir -p projects/api && cd projects/api

បើ mkdir បរាជ័យ cd នឹងមិនដែលរត់ទេ។ អ្នកនឹងឃើញ && ជារឿយៗនៅក្នុងការណែនាំអំពីការដំឡើង ដូចជា npm install && npm run dev។

7. «Port 3000 ត្រូវបានប្រើរួចហើយ»

នេះជាបញ្ហាដែលអ្នកអភិវឌ្ឍន៍ web គ្រប់រូបជួប ជាធម្មតាក្នុងសប្តាហ៍ដំបូង។ អ្នកចាប់ផ្តើម app របស់អ្នក ហើយទទួលបាន៖

Error: listen EADDRINUSE: address already in use :::3000

Port គឺជា «ទ្វារ» ដែលមានលេខ ដែលកម្មវិធីមួយបើកនៅលើកុំព្យូទ័ររបស់អ្នក ដើម្បីទទួលការតភ្ជាប់តាម network — dev server របស់អ្នក listen នៅលើ port 3000 ហើយ database មួយអាចប្រើ 5432។ មានតែ process មួយប៉ុណ្ណោះដែលអាច listen នៅលើ port មួយក្នុងពេលតែមួយ។ Error នេះមានន័យថា process ផ្សេង មួយបានកាន់ port 3000 រួចហើយ — ជាញឹកញាប់ណាស់ គឺជាច្បាប់ចាស់នៃ server របស់អ្នកខ្លួនឯង ដែលអ្នកភ្លេចទុកក្នុង terminal មួយទៀត ឬបានផ្អាកដោយ Ctrl + Z។

ដើម្បីមើលបញ្ហានេះដោយខ្លួនឯង សូមចាប់ផ្តើម web server តូចមួយនៅលើ port 3000 នៅ background (Python មានស្រាប់ក្នុង Ubuntu និង WSL។ នៅលើ macOS ការរត់ python3 លើកដំបូងអាចនឹងស្នើឲ្យដំឡើង developer tools របស់ Apple — សូមយល់ព្រម ព្រោះអ្នកនឹងត្រូវការវាសម្រាប់ Git យ៉ាងណាក៏ដោយ)៖

python3 -m http.server 3000 &

ឥឡូវសាកល្បងចាប់ផ្តើម server ទីពីរ៖

python3 -m http.server 3000
OSError: [Errno 48] Address already in use

(Linux បង្ហាញ Errno 98 ប៉ុន្តែអត្ថន័យដូចគ្នា។) ដើម្បីដឹងថា អ្នកណា កំពុងកាន់ port នោះ សូមប្រើ lsof (list open files — នៅលើ Unix ការតភ្ជាប់ network ក៏ត្រូវបានរាប់ជា file ដែរ)៖

lsof -i :3000
COMMAND   PID  USER   FD   TYPE  DEVICE  SIZE/OFF  NODE  NAME
Python  19132  dara    5u  IPv6  0x...        0t0   TCP  *:3000 (LISTEN)

នោះគឺជា PID។ ឥឡូវនេះអ្នកដឹងហើយថាត្រូវធ្វើអ្វី៖

kill 19132    # use your real PID

រត់ lsof -i :3000 ម្តងទៀត — វាមិនបង្ហាញអ្វីសោះ ដូច្នេះ port នោះទំនេរហើយ។

បើ lsof មិនទាន់បានដំឡើងនៅលើ Ubuntu ឬ WSL សូមបន្ថែមវាដោយប្រើ sudo apt install lsof។

Git Bash៖ គ្មាន lsof ទេ។ សូមប្រើ netstat -ano | grep :3000 ដើម្បីរក PID (column ចុងក្រោយ) បន្ទាប់មកបញ្ឈប់វាដោយប្រើ taskkill //PID 19132 //F។ សញ្ញា slash ពីរដងគឺជាចំណុចចម្លែករបស់ Git Bash។

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

ចាប់ផ្តើមលំហាត់នីមួយៗពី ~/cli-practice។

  1. រត់ ps បន្ទាប់មក ps aux | grep zsh (ឬ bash)។ តើអ្នកអាចរក PID នៃ shell របស់អ្នកខ្លួនឯងបានទេ?
  2. បើក top មើលវាពីរបីវិនាទី ហើយចេញដោយចុច q។ តើ process ណាដែលកំពុងប្រើ CPU ច្រើនជាងគេ?
  3. ចាប់ផ្តើម sleep 300 & ពីរដង។ ប្រើ jobs ដើម្បីមើលទាំងពីរ បន្ទាប់មកបញ្ឈប់មួយដោយប្រើ kill %1 និងមួយទៀតដោយរក PID របស់វាដោយប្រើ ps។
  4. រត់ sleep 300 ផ្អាកវាដោយចុច Ctrl + Z បន្តវានៅ background ដោយប្រើ bg ពិនិត្យ jobs ហើយចុងក្រោយបញ្ឈប់វាដោយប្រើ fg និង Ctrl + C។
  5. រត់ ls notes និង ls nothere ដោយពិនិត្យ echo $? បន្ទាប់ពីនីមួយៗ។
  6. បង្កើតបញ្ហា «port already in use» ឡើងវិញដោយប្រើ python3 -m http.server 3000 &។ រក process នោះដោយប្រើ lsof -i :3000 បញ្ឈប់វាដោយប្រើ kill ហើយបញ្ជាក់ថា port នោះទំនេរហើយ។

ឥឡូវនេះ អ្នកអាចមើល បញ្ឈប់ និងគ្រប់គ្រងកម្មវិធីដែលអ្នករត់បានហើយ។ បន្ទាប់ តោះដោះស្រាយអាថ៌កំបាំងនៅពីក្រោយ command not found៖ environment variable និង PATH។

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

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