Executing Commands Remotely via SSH

June 28 2017

SSH ကို Remote Login အတွက် SysAdmin တိုင်းသုံးကြပါတယ်။ ဒါပေမဲ့ Remote Execution အတွက်တော့ သိပ်သုံးလေ့မရှိကြပါဘူး။ စာသင်တဲ့အခါ သင်တန်းသားတွေကိုမေးကြည့်တော့လည်း တချို့တွေက Remote Login လောက်ပဲသုံးဖူးကြတာတွေ့ရတဲ့အတွက်ဒီ Post လေးရေးဖြစ်သွားတာပါ။ Server ထဲကို SSH သုံးပြီး Login ဝင်၊ ပြီးမှ ကိုယ် run ချင်တဲ့ command run တာ၊ ပြင်ချင်တဲ့ config ပြင်တာတွေကို လုပ်ကြတာများပါတယ်။ အမှန်က သုံးချင်တဲ့ command ကို SSH ကနေတဆင့် တန်း run လို့ရပါတယ်။ ဥပမာ -

$ ssh user1@server1.example.com ls -l /

server1.example.com ဆိုတဲ့ server ထဲကို user1 ဆိုတဲ့ user account နဲ့ Login ဝင်ပြီး ls -l / ဆိုတဲ့ command ကို run တာမျိုးပါ။

Command သုံးလေးခုကို တန်း run ချင်ရင်တော့ ; လေးနဲ့ခြားပြီး တန်းစီရေးသွားလို့ရပါတယ်။

$ ssh user1@server1.example.com ls -l /; pwd; ip addr

user1 အနေနဲ့သုံးခွင့်ရှိတဲ့ command တွေကိုတော့ အဆင်ပြေပြေသုံးလို့ရပေမဲ့ root privilege လိုအပ်တဲ့ command မျိုးသုံးဖို့လိုလာခဲ့ရင်တော့ root account ဒါမှမဟုတ် sudo command ကိုသုံးရပါလိမ့်မယ်။ အဲဒီအခါကျ root account သုံးပြီး run ရင် ပြဿနာမရှိပေမဲ့ root account သုံးခွင့်ပိတ်ထားလို့ sudo နဲ့ run မှရမယ်ဆိုလျှင်တော့ -t option လေးသုံးပေးဖို့လိုပါတယ်။

$ ssh -t user1@server1.example.com sudo ls -l /root
[sudo] password for user1:

user1 ကတော့ sudo command သုံးခွင့်ရှိတဲ့ user ဖြစ်ဖို့တော့လိုပါတယ်။

အထက်မှာပြောခဲ့သမျှအားလုံးက command တစ်ကြောင်းတည်းအနေနဲ့ run တာတွေပါ။ အမြင်ရှင်းအောင် command တစ်ခုစီကို တစ်ကြောင်းချင်းတန်းစီခွဲရေးပြီး run ချင်ရင်တော့ single quote လေးသုံးပေးဖို့လိုပါလိမ့်မယ်။

$ var1="This is var1"
$ ssh user1@server1.example.com '
ls -l /
pwd
ip addr
echo "$var1"
'

ပထမဆုံးအကြောင်းမှာ မြင်တွေ့ရတဲ့အတိုင်း var1 ဆိုတဲ့ variable တစ်ခုထဲကို "This is var1" ဆိုတဲ့စာသားထည့်လိုက်ပါတယ်။ ပြီးမှ ssh command ရဲ့နောက်မှာ single quote နဲ့အစဖွင့်ပြီး command တစ်ကြောင်းချင်း ခွဲရေးလိုက်တာပါ။ နောက်ဆုံမှာ single quote နဲ့ပြန်ပိတ်ပြီး Enter ခေါက်လိုက်တာနဲ့ command တွေကိုတစ်ခုချင်း run ပေးသွားမှာပါ။ ဒီနေရာမှာပြောစရာရှိတာက var1 ပါ။ echo $var1 ဆိုပြီး var1 ထဲရှိတဲ့စာသားကိုရိုက်ထုတ်ထားပေမဲ့ ပေါ်လာမှာမဟုတ်ပါဘူး။ ဘာလို့လဲဆိုတော့ var1 ဆိုတဲ့ variable ကို client ဘက်မှာတည်ဆောက်ထားတာဖြစ်ပြီး remote server မှာကျ var1 မရှိတဲ့အတွက်ကြောင့်ဖြစ်ပါတယ်။ ဒီအတွက် remote server မှာ var ထဲကစာသားပေါ်စေချင်လျှင်တော့ bash -c command နဲ့အသုံးပြုမှရပါလိမ့်မယ်။ -c option ကိုသုံးတဲ့အတွက် single quote နဲ့ရေးထားတဲ့ command list ကိုတော့ double quote နဲ့ထပ်အုပ်ပေးရပါတယ်။

$ var1="This is var1"
$ ssh user1@server1.example.com bash -c "'
ls -l /
pwd
ip addr
echo "$var1"
'"

Single quote သုံးတဲ့နည်းလမ်းအပြင် နောက်ထပ်နည်းလမ်းကတော့ Heredoc (Here Document) ဆိုတဲ့နည်းလမ်းပါ။ Heredoc သုံးမယ်ဆိုရင်တော့ -

$ var1="This is var1"
$ ssh -T user1@server1.example.com << EOF
ls -l /
pwd
ip addr
echo "$var1"
EOF

အလွယ်ပြောရရင် << EOF ဆိုတဲ့သဘောက ssh command ရဲ့နောက်ပိုင်းကနေ EOF ဆိုတဲ့စာလုံးမရောက်ခင်အထိ ကြားထဲရေးထားသမျှကို remote server ဆီပို့ပေးပါလို့ပြောလိုက်တဲ့သဘောပါ။ ဒီနေရာမှာလည်း variable var1 ထဲကစာသားတွေ remote server မှာအသုံးပြုနိုင်ဖို့အတွက် EOF ကို single quote လေးထဲမှာထည့်ပေးဖို့လိုပါတယ်။

$ var1="This is var1"
$ ssh -T user1@server1.example.com << 'EOF'
ls -l /
pwd
ip addr
echo "$var1"
EOF

-T option ကို သုံးပေးရတဲ့အကြောင်းအရင်းကတော့ -

Pseudo-terminal will not be allocated because stdin is not a terminal.

ဆိုတဲ့ warning စာသားကို မမြင်ချင်လို့ပါ။

ဒီနည်းလမ်းတွေအကုန်လုံးက command လေးငါးဆယ်ကြောင်းလောက်အတွက်တော့ အဆင်ပြေပေမဲ့ ဒီထက်ပိုတဲ့ command တွေကို Loop တွေ Conditional Statement တွေအသုံးပြုပြီးရေးမယ်ဆိုရင်တော့ သုံးရတာခက်ခဲလာပါလိမ့်မယ်။ ဘာကြောင့်လည်းဆိုတော့ Text Editor တစ်ခုခုထဲမှာရေးသလိုမဟုတ်တဲ့အတွက်ပါ။ ဒီလိုအခြေအနေမှာအကောင်းဆုံးကတော့ Script တစ်ခုအနေနဲ့ရေးပြီး အဲဒီ script ကို stdin < သုံးပြီး remote server မှာ run ခိုင်းတာကပိုအဆင်ပြေပါတယ်။

$ cat script.sh
var1="This is var1"
ls -l /
pwd
ip addr

if [ -z "$var1" ]; then
	echo "var1 not found"
else
	echo "$var1"
fi

ls -l /root
$ ssh -T user1@server1.example.com < script.sh

မြင်တွေ့ရတဲ့အတိုင်းပါပဲ နမူနာ script ထဲမှာ ရေးထားတဲ့ နောက်ဆုံးစာကြောင်း ls -l /root ကတော့ root privilege လိုတဲ့အတွက် Permission denied ဖြစ်နေပါလိမ့်မယ်။ ဒီလိုအခြေအနေမျိုးမှာ user1 အစား root အနေနဲ့ run ခိုင်းရင်တော့အဆင်ပြေပါလိမ့်မယ်။ အကယ်၍များ root account သုံးခွင့်မရှိပဲ sudo ကိုသာပေးသုံးခွင့်ပေးထားတဲ့ environment မျိုးမှာတော့ script ကို base64 နဲ့ encode လုပ်ပြီး remote server ဆီကိုပို့ပေးတာက အဆင်အပြေဆုံးနည်းလမ်းပါပဲ။

MYSCRIPT=$(base64 -w0 script.sh)
ssh -t user1@server1.example.com "echo $MYSCRIPT | base64 -d | sudo bash"

(OR)

$ ssh -t user1@server1.example.com "echo `base64 -w0 script.sh` | base64 -d | sudo bash"

လုပ်ငန်းခွင်မှာ လိုအပ်သလိုထည့်သွင်းအသုံးချနိုင်ကြပါစေ…။ 😉

Post အရမ်းရှည်သွားမှာစိုးတဲ့အတွက် Shell environment နဲ့ SSH တို့ရဲ့ အချို့အကြောင်းအရာတွေကိုအသေးစိပ်မပြောထားပါဘူး။ Unix/Linux အခြေခံရှိပြီးသားသူများအတွက်သာရည်ရွယ်ပြီးရေးသားထားခြင်းဖြစ်ပါတယ်။


comments powered by Disqus