နားလည်ထားရမယ့် အချက်
Pipe နှင့် redirection တို့သည် independent program များကို monolithic script တစ်ခုတည်းအဖြစ် ရေးစေမည့်အစား ချိတ်ဆက်ပေးသောနည်းလမ်းဖြစ်ပြီး — ၎င်းသည် Unix philosophy ကို လက်တွေ့ အသုံးချထားခြင်းပင်ဖြစ်သည်: သေးငယ်ပြီး focus ကျသော tool များကို ပေါင်းစည်းလိုက်ခြင်း။ Pipe (|) က command တစ်ခု၏ stdout ကို နောက် command ၏ stdin ထဲသို့ တိုက်ရိုက် ချိတ်ဆက်ပေးသဖြင့်၊ printf ... | wc -l သည် intermediate file တစ်ခုမျှ မရေးဘဲ line count ရရှိစေပြီး၊ grep -v banana | sort က filter တစ်ခုကို sort တစ်ခုနှင့် ကြားခံ temporary state မရှိဘဲ ချိတ်ဆက်ပေးသည် — chain ထဲရှိ command တစ်ခုစီသည် concurrently run နေပြီး data စီးဆင်းနေစဉ် pipe မှတစ်ဆင့် ဖတ်ရေးနေသည်။ Redirection operator များကမူ command အခြားတစ်ခုအစား file ပေါ်တွင် အလုပ်လုပ်သည် — > က command ၏ stdout ကို file တစ်ခုသို့ ပို့ပေးပြီး ယခင်ရှိနေသည်ကို overwrite လုပ်ပစ်ကာ၊ >> ကမူ existing content ကို ထိန်းသိမ်းရင်း အဆုံးသို့ append လုပ်ပေးသည် — ဤနှစ်ခုကို ရောထွေးမိခြင်းသည် log file တစ်ခု၏ history ကို မတော်တဆ ဖျက်ပစ်မိခြင်း၏ အဖြစ်များသော အကြောင်းရင်းတစ်ခုဖြစ်သည်။ stdout နှင့် stderr ကို 1>out.txt 2>err.txt ကဲ့သို့ သီးခြားစီ redirect လုပ်နိုင်ခြင်း၏ အကြောင်းရင်းမှာ ၎င်းတို့သည် file descriptor 1 နှင့် 2 အသီးသီးဖြင့် ခွဲခြားသတ်မှတ်ထားသော လုံးဝ separate stream များ တကယ်ဖြစ်နေသောကြောင့်ဖြစ်သည်; 2>&1 က stderr ကို stdout လက်ရှိ point လုပ်နေသည့်နေရာသို့ merge လုပ်ပေးပြီး၊ မလိုအပ်သော output ကို /dev/null သို့ redirect လုပ်ခြင်းက script ၏ ကျန်ရှိသော output ကို ပုံမှန်အတိုင်း ဆက်လက် ပေါ်ထွက်စေရင်း ၎င်းကို လုံးဝ ပယ်ဖျက်ပစ်လိုက်သည်။ Here-document (<<EOF ... EOF) နှင့် here-string (<<<) တို့ကမူ concept တစ်ခုလုံးကို ဆန့်ကျင်ပြန်လှန်ထားသည် — command ၏ output တစ်ခုခုသို့ သွားမည့်အစား ၎င်းတို့က literal text ကို command ၏ stdin ထဲသို့ ကျွေးပေးသည်၊ ၎င်းသည် disk ပေါ်တွင် file သီးခြား မလိုအပ်ဘဲ multi-line content ဖန်တီးရန် သို့မဟုတ် value တစ်ခုတည်း ထောက်ပံ့ပေးရန် နည်းလမ်းပင်ဖြစ်သည်။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
ပုံမှန် CI သို့မဟုတ် deployment script တစ်ခုသည် command output ကို error keyword ရှိမရှိစစ်ဆေးရန် grep ဖြင့် pipe ချိတ်နိုင်သလို၊ အရေးမကြီးသော noisy output များကို /dev/null သို့ redirect လုပ်ရင်း error များကို နောင်အတွက် ဆက်လက် capture လုပ်နိုင်ပြီး၊ file တစ်ခုကို inline generate လုပ်ရန် here-document ကို သုံးနိုင်သည် — ဤ lesson ၏ code သည် mechanism များကို ရှင်းလင်းစွာ မြင်နိုင်ရန် ဤအရာတစ်ခုစီကို သီးခြားစီ ပြသထားသည်။ printf "apple\nbanana\ncherry\n" | wc -l က pipe အရိုးရှင်းဆုံးကို ပြသသည် — line သုံးကြောင်း ဝင်လာပြီး count 3 ထွက်လာသည်၊ file တစ်ခုမျှ မပါဝင်ပါ။ grep -v banana | sort က ထပ်ပြီး ချိတ်ဆက်သည် — line တစ်ကြောင်းကို ဖယ်ရှားပြီးနောက် ကျန်ရှိသည်ကို sort လုပ်သည်၊ ၎င်းသည် manual filtering နှင့် looping line များစွာ ရေးရမည့်အစား pipeline သေးငယ်တစ်ခုက အစားထိုးပေးနည်းပင်ဖြစ်သည်။ redirection block သည် { ... } group အတွင်း 1>"$out_file" 2>"$out_file.err" ကိုသုံး၍ stdout နှင့် stderr ကို file နှစ်ခုအဖြစ် တမင် ခွဲခြားပေးသည်၊ ၎င်းသည် normal output နှင့် error output ကို log သီးခြားစီ ထားလိုသော script အမှန်တစ်ခုတွင် သင်သုံးမည့် pattern ဖြစ်ပြီး — ထို့နောက် ဆန့်ကျင်ဘက် 2>&1 ကို ပြသသည်၊ ၎င်းက နှစ်ခုစလုံးကို file တစ်ခုတည်းထဲ merge လုပ်ပေးသဖြင့် message နှစ်ခုစလုံး အတူတကွ ရောက်ရှိသည် — file နှစ်ခု စစ်ဆေးစရာမလိုဘဲ debug လုပ်ချင်သည့်အခါ လိုချင်သည့် behavior ဖြစ်သည်။ /dev/null ဥပမာက script ၏ ပတ်ဝန်းကျင်ရှိ normal output ကို မထိခိုက်ဘဲ line တစ်ကြောင်းတည်း၏ output ကို ဘယ်လို တိတ်ဆိတ်စေမည်ကို ပြသသည်။ နောက်ဆုံးတွင် here-document သည် fixed line သုံးကြောင်းပါသော message ကို template file သီးခြားမလိုဘဲ cat ၏ stdin ထဲသို့ ကျွေးပေးပြီး၊ here-string ကမူ value တစ်ခုတည်းဖြစ်သော "hello-there" ကို read -r မှတစ်ဆင့် word variable ထဲသို့ တိုက်ရိုက် ဖတ်ပေးသည် — argument အဖြစ် လက်ခံမည့်အစား stdin မှ ဖတ်ရန် မျှော်လင့်ထားသော command တစ်ခုထဲသို့ value တစ်ခုတည်းကို လျင်မြန်စွာ ကျွေးပေးနည်းတစ်ခုဖြစ်သည်။
အတူတူ စမ်းရေးကြည့်မယ်
#!/bin/bash
echo "Piping ls-like data through wc:"
printf "apple\nbanana\ncherry\n" | wc -l
echo ""
echo "Chaining grep and sort in a pipeline:"
printf "banana\napple\ncherry\n" | grep -v banana | sort
echo ""
echo "Redirecting stdout to a file, then reading it back:"
out_file=$(mktemp)
echo "saved output" > "$out_file"
cat "$out_file"
echo ""
echo "Appending more output to the same file:"
echo "second line" >> "$out_file"
cat "$out_file"
echo ""
echo "Redirecting stderr separately from stdout:"
{ echo "this is stdout"; echo "this is stderr" >&2; } 1>"$out_file" 2>"$out_file.err"
echo "stdout file contains:"
cat "$out_file"
echo "stderr file contains:"
cat "$out_file.err"
echo ""
echo "Discarding output with /dev/null:"
echo "you will not see this" > /dev/null
echo "but this line still prints"
echo ""
echo "Combining stdout and stderr with 2>&1:"
{ echo "normal message"; echo "error message" >&2; } > "$out_file" 2>&1
cat "$out_file"
echo ""
echo "Here-document: sending multi-line input to cat"
cat <<EOF
Line one
Line two
Line three
EOF
echo ""
echo "Here-string: sending a single value to a command"
read -r word <<< "hello-there"
echo "Read from here-string: $word"
rm -f "$out_file" "$out_file.err"ဤ script ကို run လိုက်လျှင် အောက်ပါအတိုင်း output ရရှိမည်−
Piping ls-like data through wc:
3
Chaining grep and sort in a pipeline:
apple
cherry
Redirecting stdout to a file, then reading it back:
saved output
Appending more output to the same file:
saved output
second line
Redirecting stderr separately from stdout:
stdout file contains:
this is stdout
stderr file contains:
this is stderr
Discarding output with /dev/null:
but this line still prints
Combining stdout and stderr with 2>&1:
normal message
error message
Here-document: sending multi-line input to cat
Line one
Line two
Line three
Here-string: sending a single value to a command
Read from here-string: hello-there၅ မိနစ် စမ်းကြည့်
number list အသေးလေးတစ်ခု၏ output ကို grep ဖြင့် pipe ချိတ်ပြီး ကိုက်ညီသည့် pattern များကိုသာ ချန်ထားကာ (hint: pattern ကို match ပါ)၊ ရလဒ် filter ကို file တစ်ခုသို့ redirect လုပ်ပြီး၊ short multi-line message တစ်ခုကို terminal ပေါ်တွင် print ထုတ်ရန် here-document ကို သီးခြားသုံးသော script တစ်ခု ရေးပါ။
သတိလေးတစ်ချက်
command > file 2>&1 ကို command 2>&1 > file ဟု အစီအစဉ်မှားရေးခြင်း — stdout ကို redirect မလုပ်ရသေးမီ 2>&1 ကို evaluate လုပ်ပစ်လိုက်သောကြောင့် stderr သည် file အစား terminal ဆီသို့ ရောက်သွားသည်
append လုပ်လိုသော်လည်း >> အစား > ကိုသုံးမိခြင်း — file ၏ previous content များကို တိတ်တဆိတ် ဖျက်ပြီး overwrite လုပ်ပစ်လိုက်သည်
GNU Bash Manual: Redirections — Bash / Shell Scripting