技術(shù)員聯(lián)盟提供win764位系統(tǒng)下載,win10,win7,xp,裝機(jī)純凈版,64位旗艦版,綠色軟件,免費(fèi)軟件下載基地!

當(dāng)前位置:主頁 > 教程 > 服務(wù)器類 >

Linux中rsh遠(yuǎn)程shell命令的使用技巧解析

來源:技術(shù)員聯(lián)盟┆發(fā)布時(shí)間:2018-01-09 12:22┆點(diǎn)擊:

  rsh有兩種使用模式:

  rsh $host : 遠(yuǎn)程登錄,啟動(dòng)交互式進(jìn)程。

  rsh $host $command :遠(yuǎn)程執(zhí)行命令,并顯示輸出。

  rsh hosthostcommand

  rsh $host $command的作用是:

  1.在遠(yuǎn)程機(jī)器上執(zhí)行命令$command

  2.通過網(wǎng)絡(luò)連接(socket)重定向當(dāng)前進(jìn)程和遠(yuǎn)端進(jìn)程的標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)輸出

  3.遠(yuǎn)端rsh進(jìn)程在遠(yuǎn)端進(jìn)程結(jié)束后結(jié)束

  4.本地rsh進(jìn)程讀取遠(yuǎn)端進(jìn)程的標(biāo)準(zhǔn)輸出直到結(jié)束(EOF)

  深刻理解這個(gè)執(zhí)行過程有助于理解各種“奇怪”的現(xiàn)象和用法。

  代碼如下:

  + Suspended (tty input)

  $ rsh localhost infinite-loop &

  [1] + Suspended (tty input) rsh pv007 infinite-loop

  $ rsh -n localhost infinite-loop &

  # 執(zhí)行正常

  后臺執(zhí)行rsh命令時(shí),提示了和標(biāo)準(zhǔn)輸入相關(guān)的錯(cuò)誤信息。這是因?yàn)閞sh默認(rèn)會(huì)把當(dāng)前窗口的標(biāo)準(zhǔn)輸入重定向到遠(yuǎn)端進(jìn)程。

  而本地rsh進(jìn)程作為后臺程序運(yùn)行的話,標(biāo)準(zhǔn)輸入被“阻塞”了。

  通過-n選項(xiàng)制定不需要重定向標(biāo)準(zhǔn)輸入(stdin)。

  遠(yuǎn)端進(jìn)程的執(zhí)行

  執(zhí)行命令

  代碼如下:

  rsh somehost infinite-loop

  在遠(yuǎn)端機(jī)器上查看相關(guān)進(jìn)程:

  代碼如下:

  $ pstree -a -p 3353

  in.rshd,3353

  └─csh,3363 -c infinite-loop

  └─infinite-loop,3632 /u/szhang/bin/infinite-loop

  可以看出,遠(yuǎn)端機(jī)器上的rshd進(jìn)程負(fù)責(zé)啟動(dòng)遠(yuǎn)端進(jìn)程。而且可以看出是通過csh -c的方式啟動(dòng)的(這里用戶的默認(rèn)Shell是C Shell)。

  遠(yuǎn)端進(jìn)程的標(biāo)準(zhǔn)IO

  檢查遠(yuǎn)端進(jìn)程的文件描述符:

  代碼如下:

  $ ls -l /proc/3363/fd /proc/3632/fd

  /proc/3363/fd:

  total 0

  lrwx------. 1 Jul 30 23:47 16 -> socket:[1184748899]

  lrwx------. 1 Jul 30 23:47 17 -> socket:[1184748899]

  l-wx------. 1 Jul 30 23:47 18 -> pipe:[1184749092]

  lrwx------. 1 Jul 30 23:47 19 -> socket:[1184748899]

  代碼如下:

  /proc/3632/fd:

  total 0

  lrwx------. 1 Jul 30 23:47 0 -> socket:[1184748899]

  lrwx------. 1 Jul 30 23:47 1 -> socket:[1184748899]

  l-wx------. 1 Jul 30 23:47 2 -> pipe:[1184749092]

  可以看出遠(yuǎn)端里程的標(biāo)準(zhǔn)輸入輸出是被重定向到socket上的:

  1.stdin 和 stdout 共享一個(gè)socket連接

  2.stderr 則通過一個(gè)pipe重定向(重定向到stdout ???)

  3.rsh 的返回值

  rsh程序自身的返回值表明的是rsh自身的運(yùn)行狀況,而不是遠(yuǎn)端進(jìn)程的返回值。

  獲得遠(yuǎn)端進(jìn)程的返回值

  代碼如下:

  # 遠(yuǎn)端是C Shell

  $ rsh $host "$command ; echo $status"

  代碼如下:

  # 遠(yuǎn)端是Bash Shell

  $ rsh $host "$command ; echo $?"

  代碼如下:

  # 遠(yuǎn)端Shell類型不確定

  $ rsh $host "sh -c '$command ; echo $?'"

  啟動(dòng)遠(yuǎn)端進(jìn)程所用的Shell

  由于用于啟動(dòng)遠(yuǎn)端進(jìn)程的Shell類型是未知的,而有些操作的語法在不同Shell里是不同的。

  比如輸入輸出重定向、命令返回值等。

  解決該問題的方法之一是通過明確指定的Shell來啟動(dòng)真正需要的里程。比如:

  代碼如下:

  # 不確定遠(yuǎn)端Shell的類型,顯式通過Bash Shell來啟動(dòng)需要的進(jìn)程

  $ rsh -n $host "sh -c '$command > /dev/null 2>&1'"

  另一種思路,則是通過一個(gè)wrapper程序來啟動(dòng)真正的命令。

  通過rsh在遠(yuǎn)端執(zhí)行后臺進(jìn)程

  想在遠(yuǎn)端機(jī)器上執(zhí)行后臺進(jìn)程。命令rsh $host "$command &"是不起作用的,會(huì)導(dǎo)致本地的rsh進(jìn)程不能結(jié)束。

  背后的原因應(yīng)該是,$command的標(biāo)準(zhǔn)輸入輸出通常仍然綁定在rsh連接的socket上,從而導(dǎo)致本地的rsh進(jìn)程無法讀取到文件結(jié)束符EOF。

  知道了原因就知道該怎么辦了,關(guān)鍵是關(guān)閉后臺進(jìn)程續(xù)定在rsh連接上的標(biāo)準(zhǔn)輸入輸出。

  代碼如下:

  # 如果遠(yuǎn)端Shell是C Shell

  $ rsh -n $host "$command >& /dev/null &"

  代碼如下:

  # 如果遠(yuǎn)端Shell是Bash Shell

  $ rsh -n $host "$command > /dev/null 2>&1 &"

  代碼如下:

  # 不確定遠(yuǎn)端Shell的類型

  $ rsh -n $host "sh -c '$command > /dev/null 2>&1 &'"

  但上面這樣重定向的辦法有個(gè)缺點(diǎn)是不能得到任何遠(yuǎn)端進(jìn)程的輸出,而有時(shí)我們希望獲得一些輸出信息。

  這時(shí)就需要遠(yuǎn)端進(jìn)程能夠以守護(hù)進(jìn)程(daemon)的方式運(yùn)行。

  這種情況下,rsh命令可以簡單地寫作:$ rsh -n $host "$command &"

  遠(yuǎn)端后臺進(jìn)程的內(nèi)容用Tcl表示,大意如下:

  代碼如下:

  #/bin/env tclsh

  puts "I am a background job"

  puts "This Can Be Seen by Remote rsh Process"

  close stdout

  close stderr

  # rsh連接到此應(yīng)該結(jié)束。

  puts "This Can NOT Be Seen by Remote rsh Process"

  更進(jìn)就步,我們可以甚至忽略rsh命令中的后臺運(yùn)行符:$ rsh -n $host "$command"

  這時(shí)遠(yuǎn)端進(jìn)程需要通過fork的方式結(jié)束自己,并啟動(dòng)真正的后臺進(jìn)程(守護(hù)進(jìn)程)。

  rsh進(jìn)程的阻塞和超時(shí)處理

  在程序中調(diào)用rsh $host $command時(shí)可能由于各種奇怪的原因發(fā)生rsh進(jìn)程的阻塞,這不是我們希望看到的。

  我們希望設(shè)置一個(gè)超時(shí)(timeout)機(jī)制來解決這個(gè)問題。

  在Tcl程序中的一種實(shí)現(xiàn)可以這樣: TODO

  TCP Connection連接數(shù)過多引起的rsh失敗

  監(jiān)控郵件顯示rsh $host $command命令失敗,錯(cuò)誤提示為“poll: protocol failure in circuit setup"

  懷疑是網(wǎng)絡(luò)連接數(shù)過多所引起。

  rsh $host $command 的網(wǎng)絡(luò)連接過程

  命令rsh $host連接遠(yuǎn)程主機(jī)的513端口。