当前位置: 首页 > news >正文

linux rsh用法,Linux中rsh远程shell命令的使用技巧解析

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

相关文章:

  • C语言字符输入回车时停止,解决C语言输入单个字符屏蔽回车符的问题
  • 二分法查找字符串 c语言,c语言二分法如何实现查找数组元素
  • c++语言常量,C++常量(constant)
  • 64平台的c语言int类型值比32平台大,C语言数据类型32位和64位不同
  • c语言输入10个数从小,C语言中,从键盘输入10个数,从小到大排列输出,怎
  • 得到 android组件,android 获取HOME组件的Activity信息
  • android studio视频路径,Android studio相关设置及实现存在于工程目录中的视频播放...
  • android wear 1.6,玩的就是情怀 外国网友将CS 1.6移植到了Android Wear上
  • ability鸿蒙,Day8 鸿蒙,一个Ability全家桶究竟包括了什么(一)
  • Android网页文字进度,Android webview 进度显示
  • android仿qq侧滑删除,Android仿QQ微信侧滑删除效果
  • html 重置样式表,CSS 浏览器样式重置终结版
  • 压缩html源文件,js代码压缩还原详解
  • html5随机选取文本框,HTML5交互式电子邮件(带输入框和选择框)
  • html格子切换效果图,(HTML)关于格子流布局方案可以如此设计
  • [ 一起学React系列 -- 8 ] React中的文件上传
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • express.js的介绍及使用
  • happypack两次报错的问题
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • java取消线程实例
  • Laravel Mix运行时关于es2015报错解决方案
  • leetcode46 Permutation 排列组合
  • linux安装openssl、swoole等扩展的具体步骤
  • PHP 的 SAPI 是个什么东西
  • Puppeteer:浏览器控制器
  • SegmentFault 2015 Top Rank
  • 从零开始的无人驾驶 1
  • 从伪并行的 Python 多线程说起
  • 利用DataURL技术在网页上显示图片
  • 前端临床手札——文件上传
  • 手写双向链表LinkedList的几个常用功能
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 以太坊客户端Geth命令参数详解
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • 我们雇佣了一只大猴子...
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • #07【面试问题整理】嵌入式软件工程师
  • #宝哥教你#查看jquery绑定的事件函数
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (06)Hive——正则表达式
  • (CVPRW,2024)可学习的提示:遥感领域小样本语义分割
  • (day 12)JavaScript学习笔记(数组3)
  • (pojstep1.3.1)1017(构造法模拟)
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (四) 虚拟摄像头vivi体验
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (四)库存超卖案例实战——优化redis分布式锁
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转)3D模板阴影原理