欢迎登陆真网站,您的到来是我们的荣幸。 登陆 注册 忘记密码? ☆设为首页 △加入收藏
欢迎加入真幸福QQ群
电脑知识: 基础知识 网络技术 操作系统 办公软件 电脑维修 电脑安全 windows7 windows8 windows10 服务器教程 平板电脑 视频播放教程 网络应用 互联网 工具软件 浏览器教程 QQ技巧 输入法教程 影视制作 YY教程 wps教程 word教程 Excel教程 PowerPoint
云南西双版纳特产小花糯玉米真空包装


如何用爱剪辑快速剪辑视频
重装系统后电脑声卡怎么调试?
U精灵如何制作ISO镜像文件包
U精灵U盘启动盘制作工具介绍
U精灵U盘启动盘如何制作
百度云出现‘’服务器有点儿忙,稍候重试一下吧‘’’怎么办
如何把本地音乐弄到我的QQ音乐里
百度网盘如何直接下载大文件
Win7系统不能新建Word文档怎么办?
Zend Studio使用教程如何设置简体中文
Linux中rsh远程shell命令的使用技巧解析
【 来源:网络 】【 点击:1 】 【 发布时间:2017_03_03 08:59:59 】

   rsh有两种使用模式:

  rsh $host : 远程登录,启动交互式进程。

  rsh $host $command :远程执行命令,并显示输出。

  rsh hosthostcommand

  rsh $host $command的作用是:

  1.在远程机器上执行命令$command

  2.通过网络连接(socket)重定向当前进程和远端进程的标准输入和标准输出

  3.远端rsh进程在远端进程结束后结束

  4.本地rsh进程读取远端进程的标准输出直到结束(EOF)

  深刻理解这个执行过程有助于理解各种“奇怪”的现象和用法。

  代码如下:

  + Suspended (tty input)

  $ rsh localhost infinite-loop &

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

  $ rsh -n localhost infinite-loop &

  # 执行正常

  后台执行rsh命令时,提示了和标准输入相关的错误信息。这是因为rsh默认会把当前窗口的标准输入重定向到远端进程。

  而本地rsh进程作为后台程序运行的话,标准输入被“阻塞”了。

  通过-n选项制定不需要重定向标准输入(stdin)。

  远端进程的执行

  执行命令

  代码如下:

  rsh somehost infinite-loop

  在远端机器上查看相关进程:

  代码如下:

  $ pstree -a -p 3353

  in.rshd,3353

  └─csh,3363 -c infinite-loop

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

  可以看出,远端机器上的rshd进程负责启动远端进程。而且可以看出是通过csh -c的方式启动的(这里用户的默认Shell是C Shell)。

  远端进程的标准IO

  检查远端进程的文件描述符:

  代码如下:

  $ 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]

  可以看出远端里程的标准输入输出是被重定向到socket上的:

  1.stdin 和 stdout 共享一个socket连接

  2.stderr 则通过一个pipe重定向(重定向到stdout ???)

  3.rsh 的返回值

  rsh程序自身的返回值表明的是rsh自身的运行状况,而不是远端进程的返回值。

  获得远端进程的返回值

  代码如下:

  # 远端是C Shell

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

  代码如下:

  # 远端是Bash Shell

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

  代码如下:

  # 远端Shell类型不确定

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

  启动远端进程所用的Shell

  由于用于启动远端进程的Shell类型是未知的,而有些操作的语法在不同Shell里是不同的。

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

  解决该问题的方法之一是通过明确指定的Shell来启动真正需要的里程。比如:

  代码如下:

  # 不确定远端Shell的类型,显式通过Bash Shell来启动需要的进程

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

  另一种思路,则是通过一个wrapper程序来启动真正的命令。

  通过rsh在远端执行后台进程

  想在远端机器上执行后台进程。命令rsh $host "$command &"是不起作用的,会导致本地的rsh进程不能结束。

  背后的原因应该是,$command的标准输入输出通常仍然绑定在rsh连接的socket上,从而导致本地的rsh进程无法读取到文件结束符EOF。

  知道了原因就知道该怎么办了,关键是关闭后台进程续定在rsh连接上的标准输入输出。

  代码如下:

  # 如果远端Shell是C Shell

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

  代码如下:

  # 如果远端Shell是Bash Shell

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

  代码如下:

  # 不确定远端Shell的类型

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

  但上面这样重定向的办法有个缺点是不能得到任何远端进程的输出,而有时我们希望获得一些输出信息。

  这时就需要远端进程能够以守护进程(daemon)的方式运行。

  这种情况下,rsh命令可以简单地写作:$ rsh -n $host "$command &"

  远端后台进程的内容用Tcl表示,大意如下:

  代码如下:

  #/bin/env tclsh

  puts "I am a background job"

  puts "This Can Be Seen by Remote rsh Process"

  close stdout

  close stderr

  # rsh连接到此应该结束。

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

  更进就步,我们可以甚至忽略rsh命令中的后台运行符:$ rsh -n $host "$command"

  这时远端进程需要通过fork的方式结束自己,并启动真正的后台进程(守护进程)。

  rsh进程的阻塞和超时处理

  在程序中调用rsh $host $command时可能由于各种奇怪的原因发生rsh进程的阻塞,这不是我们希望看到的。

  我们希望设置一个超时(timeout)机制来解决这个问题。

  在Tcl程序中的一种实现可以这样: TODO

  TCP Connection连接数过多引起的rsh失败

  监控邮件显示rsh $host $command命令失败,错误提示为“poll: protocol failure in circuit setup"

  怀疑是网络连接数过多所引起。

  rsh $host $command 的网络连接过程

  命令rsh $host连接远程主机的513端口。

  命令rsh $host $command则连接远程主机的514端口,并随后发送一个本地端口号给远程主机,要求远程主机建立一个新的TCP连接到这个端口(还不清楚这个新的连接有什么作用)。然后才是传送命令和等待命令结束。

  这样做的结果就是在rsh $host $command进程过多时,本地开放的端口资源被消耗完了,从而导致新的rsh $host $command失败。

  这是rsh $host的使用则依然正常。

  这里提到的rsh的缺陷,也是建议尽量使用ssh的原因之一。

  没有完全关闭的网络连接:

  在远程主机上kill掉相关的rsh进程后,会导致TCP连接没有完全关闭。

  netstat命令显示CLOSE_WAIT状态,端口资源并没有释放出来。

  根据配置文件/proc/sys/net/ipv4/tcp_keepalive_time显示,需要等待2个小时,那些端口才会因为超时而被真正关闭,从而释放出来。

  代码如下:

  %> netstat -a | grep localhost

  tcp 0 0 localhost:933 localhost:935 CLOSE_WAIT

  %> cat /proc/sys/net/ipv4/tcp_keepalive_time

  7200 ;# in seconds. = 2 hours

  %> echo "net.ipv4.tcp_keepalive_time = 120" >> /etc/sysctl.con

本网站由川南居提供技术支持,fkzxf版权所有 浙ICP备12031891号
淳安分站 淳安分站