从 SSH 会话中分离命令
Detach command from SSH session
我需要通过 SSH 会话在服务器上 运行 命令并关闭会话而不终止服务器上的进程。如何正确实施。
服务器和客户端是linux个系统。
请注意,我无法在服务器上安装其他软件。
看看reptyr。它是一个用于获取现有 运行 程序并将其附加到新终端的实用程序。您只需要启动一个屏幕,使用 reptyr
抓取它,然后终止 ssh 会话。 reptyr
的工作原理是使用 ptrace(2)
附加到目标程序,重定向相关文件描述符,并更改程序的控制终端。附加程序后,该程序将显示为后台运行或暂停到 shell 启动它(取决于
shell)。最好在旧的 shell 中使用 bg; disown
来删除与程序的关联,但是 reptyr
会尝试确保目标程序仍然是 运行
即使您不这样做就关闭了 shell。
如果安装了 screen
或 tmux
实用程序,您可以使用它。
在我看来,nohup
是最好的工具。
只需像这样使用它:
nohup command &
If standard input is a terminal, redirect it from /dev/null. If
standard output is a terminal, append output to 'nohup.out' if
possible, '$HOME/nohup.out' otherwise. If standard error is a
terminal, redirect it to standard output. To save output to FILE, use
'nohup COMMAND > FILE'.
使用特殊工具之前
理解
当我尝试在目标上进行后台作业时,为什么 ssh 没有 return。
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
引用 after 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
...
最多创建您自己的包装...
我需要通过 SSH 会话在服务器上 运行 命令并关闭会话而不终止服务器上的进程。如何正确实施。
服务器和客户端是linux个系统。
请注意,我无法在服务器上安装其他软件。
看看reptyr。它是一个用于获取现有 运行 程序并将其附加到新终端的实用程序。您只需要启动一个屏幕,使用 reptyr
抓取它,然后终止 ssh 会话。 reptyr
的工作原理是使用 ptrace(2)
附加到目标程序,重定向相关文件描述符,并更改程序的控制终端。附加程序后,该程序将显示为后台运行或暂停到 shell 启动它(取决于
shell)。最好在旧的 shell 中使用 bg; disown
来删除与程序的关联,但是 reptyr
会尝试确保目标程序仍然是 运行
即使您不这样做就关闭了 shell。
如果安装了 screen
或 tmux
实用程序,您可以使用它。
nohup
是最好的工具。
只需像这样使用它:
nohup command &
If standard input is a terminal, redirect it from /dev/null. If standard output is a terminal, append output to 'nohup.out' if possible, '$HOME/nohup.out' otherwise. If standard error is a terminal, redirect it to standard output. To save output to FILE, use 'nohup COMMAND > FILE'.
使用特殊工具之前
理解
当我尝试在目标上进行后台作业时,为什么 ssh 没有 return。
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 &'
来使用 uniq 文件>>
用于将日志添加到现有文件...您可以通过添加$$
或date +%F
...ssh user@host 'exec 0<&-;exec 1>/path/to/logfile-$$;exec 2>&1; sleep 300 &'
2>&1
引用 after1>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
...
最多创建您自己的包装...