ssh - 从 SSH 会话中分离命令
问题描述
我需要通过 SSH 会话在服务器上运行命令并关闭会话而不杀死服务器上的进程。如何正确实施。
服务器和客户端都是linux系统。
请注意,我无法在服务器上安装其他软件。
解决方案
使用特殊工具之前
理解
当我尝试在目标上执行后台作业时,为什么 ssh 不返回。
ssh user@host 'sleep 300 &'
然后你必须点击Ctrl+C来获得你的会话。
这是因为每个连接都包含 3个文件描述符:
STDIN (0)
和. 当至少有一个文件描述符正在使用时,连接将保持打开状态。STDOUT (1)
STDERR (2)
在运行后台任务之前简单地关闭它们
这大概是做什么
nohup
的。ssh user@host 'exec 0<&-;exec 1>&-;exec 2>&-; sleep 300 &'
这将完成这项工作。
将输出重定向到静态文件
您可以将输出存储在位于服务器端某处的文件中:
ssh user@host 'exec 0<&-;exec 1>>/path/to/logfile;exec 2>>/path/to/errlog; sleep 300 &'
>>
用于将日志添加到现有文件...您可以通过添加$$
或date +%F
...来使用 uniq 文件ssh user@host 'exec 0<&-;exec 1>/path/to/logfile-$$;exec 2>&1; sleep 300 &'
2>&1
引用后将1>file
重定向STDERR
为.STDOUT
_file
ssh user@host 'exec 0<&-;exec 1>/path/to/file-$(date +%F-%T).$$;exec 2>&-;sleep 300 &'
只会
STDOUT
存储在新文件中。
使用screen
如果
screen
已安装如果您能够访问交互式前端,您可以:
ssh user@host screen -dmS mySleep sh -c \ "'x=0;while [ \$x -lt 300 ];do echo \$x;x=\$((x+1));sleep 1;done'"
这将启动一个后台作业,下一秒每 300 个打印 1 个 ling,然后完成。
要重新连接,您可以
ssh -t user@host screen -x mySleep
然后Ctrl+ A,然后是d离开后台任务。
screen
水平安装user
_如果你不能在服务器中安装一些东西,也许**你可以在你的
$HOME
目录中安装一些东西:(** 如果您的架构与服务器上的架构相同,这将很容易。如果不是,您甚至可以找到兼容的二进制文件或自己交叉编译。)
$ ssh user@host user@host:~$ mkdir bin lib user@host:~$ exit $ scp /path/to/bin/screen user@host:~/bin $ ssh user@host user@host:~$ bin/screen bin/screen: error while loading shared libraries: libutempter.so.0: cannot open shared object file: No such file or directory user@host:~$ exit $ scp /path/to/lib/libutempter.so.0 user@host:~/lib $ ssh user@host user@host:~$ LD_LIBRARY_PATH=~/lib bin/screen bin/screen: /lib/x86_64-linux-gnu/libcrypt.so.1: version `XCRYPT_2.0' not found (required by bin/screen) user@host:~$ exit $ scp /lib/x86_64-linux-gnu/libcrypt.so.1 user@host:~/lib $ ssh user@host user@host:~$ LD_LIBRARY_PATH=~/lib bin/screen Cannot make directory '/run/screen': Permission denied user@host:~$ mkdir $HOME/.screen user@host:~$ SCREENDIR=$HOME/.screen LD_LIBRARY_PATH=~/lib bin/screen
最后,现在它工作了......
$ ssh user@host SCREENDIR=\~/.screen LD_LIBRARY_PATH=\~/lib bin/screen -dmS mySleep sh -c \ "'x=0;while [ \$x -lt 300 ];do echo \$x;x=\$((x+1));sleep 1;done'" $ ssh -t user@host SCREENDIR=\~/.screen LD_LIBRARY_PATH=\~/lib bin/screen -x mySleep
还有很多其他选择,例如tmux
,byobu
...
最多创建自己的包装器...
推荐阅读
- c - 为什么这段代码有效?常量数组上的 memcpy
- dropdown - materializecss 1.0.0 单击时嵌套下拉菜单(不悬停)
- sql - 在 Presto 中,NOW() 产生什么数据类型
- javascript - 使用香草js将活动元素背景设置为红色并将剩余元素设置为白色背景
- python - Django:从另一个服务捕获授权令牌
- reactjs - 部署 React 应用程序后如何解决 http/https 混合内容问题
- r - 概率矩阵 - 从任何位置开始
- node.js - TypeError:_stream.Readable.from 不是 sequelize node js 中的函数
- javascript - Vuetify - 选定的 v-radio 未在 v-model 上设置值
- r - 如何仅计算 R 中的非空列,而包含稀疏 NA 的列?