从 SSH 会话中分离命令

esa*_*tix 4 ssh process sh remote-server

我需要通过 SSH 会话在服务器上运行命令并关闭会话而不终止服务器上的进程。如何才能正确实施这一点。

服务器和客户端都是linux系统。

请注意,我无法在服务器上安装其他软件。

F. *_*uri 6

使用专用工具之前

  1. 理解

    当我尝试在目标上进行后台作业时,为什么 ssh 不返回。

    ssh user@host 'sleep 300 &'
    
    Run Code Online (Sandbox Code Playgroud)

    然后你必须点击Ctrl+C才能开始你的会话。

    这是因为每个连接保存 3 个文件描述符STDIN (0)STDOUT (1)STDERR (2)。当至少有一个文件描述符正在使用时,连接将保持打开状态

  2. 只需在运行后台任务之前关闭它们即可

    这大概就是nohup所做的事情。

    ssh user@host 'exec 0<&-;exec 1>&-;exec 2>&-; sleep 300 &'
    
    Run Code Online (Sandbox Code Playgroud)

    这样就可以完成工作了。

    或者通过使用nohup

    ssh user@host 'nohup sleep 300 &'
    
    Run Code Online (Sandbox Code Playgroud)

    也会做这份工作。

  3. 将输出重定向到静态文件

    您可以将输出存储在位于服务器端某处的文件中:

    ssh user@host 'exec 0<&-;exec 1>>/path/to/logfile;exec 2>>/path/to/errlog; sleep 300 &'
    
    Run Code Online (Sandbox Code Playgroud)

    >>为了将日志添加到现有文件...您可以通过添加$$date +%F...来使用 uniq 文件

    ssh user@host 'exec 0<&-;exec 1>/path/to/logfile-$$;exec 2>&1; sleep 300 &'
    
    Run Code Online (Sandbox Code Playgroud)

    2>&1之后 引用1>file将重定向STDERR至.STDOUTfile

    ssh user@host 'exec 0<&-;exec 1>/path/to/file-$(date +%F-%T).$$;exec 2>&-;sleep 300 &'
    
    Run Code Online (Sandbox Code Playgroud)

    只会STDOUT存储在新文件中。

使用screen

  1. 如果screen安装了

    如果您能够访问交互式前端,您可以:

    ssh user@host screen -dmS mySleep sh -c \
              "'x=0;while [ \$x -lt 300 ];do echo \$x;x=\$((x+1));sleep 1;done'"
    
    Run Code Online (Sandbox Code Playgroud)

    这将启动后台作业,下一秒每 300 打印 1 个 ling,然后完成。

    要重新连接它,您可以

    ssh -t user@host screen -x mySleep
    
    Run Code Online (Sandbox Code Playgroud)

    然后Ctrl+ A,然后d离开后台任务。

  2. screen水平安装user

    如果您无法在服务器中安装某些内容,也许*您可以在您的$HOME目录中安装某些内容:

    (*如果您的架构与服务器上的架构相同,这将很容易。如果不是,您甚至可以找到兼容的二进制文件或自己交叉编译。)

    ssh user@host 'sleep 300 &'
    
    Run Code Online (Sandbox Code Playgroud)

    终于,现在它可以工作了...

     $ 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
    
    Run Code Online (Sandbox Code Playgroud)

还有很多其他选择,例如tmuxbyobu...

创建您自己的包装器...