【问题标题】:how to run a command in background using ssh and detach the session如何使用 ssh 在后台运行命令并分离会话
【发布时间】:2010-12-10 08:04:08
【问题描述】:

我目前正在尝试通过 ssh 连接到远程机器并运行脚本,然后让节点运行脚本。下面是我的脚本。但是,当它运行时,脚本在机器上成功运行,但 ssh 会话挂起。有什么问题?

ssh -x $username@$node 'rm -rf statuslist
                        mkdir statuslist
                        chmod u+x ~/monitor/concat.sh
                        chmod u+x ~/monitor/script.sh
                        nohup ./monitor/concat.sh &
                        exit;'

【问题讨论】:

    标签: shell ssh nohup


    【解决方案1】:

    在某些情况下,您想在远程机器/服务器上执行/启动某些脚本(它将自动终止)并断开与服务器的连接。

    eg: 一个在盒子上运行的脚本,当它被执行时

    1. 获取模型并将其复制到远程服务器
    2. 创建一个脚本来运行模型的模拟并将其推送到服务器
    3. 在服务器上启动脚本并断开连接
    4. 因此启动的脚本的职责是在服务器中运行模拟,并在完成后(需要数天才能完成)将结果复制回客户端。

    我会使用以下命令:

    ssh remoteserver 'nohup /path/to/script `</dev/null` >nohup.out 2>&1 &'
    

    @CKeven,您可以将所有这些命令放在一个脚本中,将其推送到远程服务器并按如下方式启动它:

    echo '#!/bin/bash  
    rm -rf statuslist  
    mkdir statuslist  
    chmod u+x ~/monitor/concat.sh  
    chmod u+x ~/monitor/script.sh  
    nohup ./monitor/concat.sh &  
    ' > script.sh
    
    chmod u+x script.sh
    
    rsync -azvp script.sh remotehost:/tmp
    
    ssh remotehost '/tmp/script.sh `</dev/null` >nohup.out 2>&1 &'
    

    希望这可行 ;-)

    编辑: 你也可以使用 ssh user@host 'screen -S SessionName -d -m "/path/to/executable"'

    这会创建一个分离的屏幕会话并在其中运行目标命令

    【讨论】:

    • 如果您正在运行的命令需要从文件输入(例如大型数据库导入,例如 mysql
    • 如果你监控ps -ef | grep ssh,这个进程会继续运行。如果我用-9 杀死它,那很好,远程进程仍然会继续运行。有什么办法可以不让这个进程在我的本地运行,而只让远程的进程保持活跃。我尝试删除 > nohup.out,但它将输出通过管道传输到标准输出。有什么建议吗?
    【解决方案2】:

    你觉得用screen 做这个怎么样?您可以通过 ssh 运行 screen 来启动命令 (concat.sh),然后如果您想监控它,您就可以返回到屏幕会话(可能很方便,具体取决于 concat 的功能)。

    更具体地说,试试这个:

    ssh -t $username@$node screen -dm -S testing ./monitor/concat.sh
    

    您应该会发现提示立即返回,并且concat.sh 正在远程计算机上运行。我将解释一些选项:

    • ssh -t 制作 TTY。屏幕需要这个。
    • screen -dm 使其以“分离”模式启动。这就像你的目的的“背景”。
    • -S testing 为您的屏幕会话命名。这是可选的,但建议使用。

    现在,完成此操作后,您可以转到远程计算机并运行以下代码:

    screen -r testing
    

    这会将您附加到包含您的程序的屏幕会话。从那里你可以控制它、杀死它、查看它的输出等等。 Ctrl-A,然后 d 将使您与屏幕会话分离。 screen -ls 将列出所有正在运行的会话。

    【讨论】:

    • @John Zwinck,这对你有用吗?以下命令对我不起作用:ssh -t HOST "screen -dm -S sleep sleep 10"。它只是说“与主机的连接已关闭”,当我登录服务器时,没有分离的屏幕。
    • @richardkmiller:当我刚刚尝试时,我得到了和你一样的(坏的)结果。我将 -t 选项更改为 ssh 为 -f,以便它在命令后台运行(并且不分配 TTY),然后它就可以工作了。我怀疑自从我写了这个答案以来,在 Linux 的 2 年多的时间里发生了一些变化……试试ssh -f HOST "screen -dm -S sleep sleep 10",你可能会发现它现在可以工作了。
    • @JohnZwinck:太棒了,效果很好。非常感谢您的回复。
    【解决方案3】:

    它可能是标准输入流。试试ssh -n ...ssh -f ...

    【讨论】:

    • 不错。谢谢。 ssh -f "user@host DISPLAY=myhost:0.0 qtcreator &amp;"
    【解决方案4】:

    对我来说,只有这样有效:

    screen -dmS name sh my-script.sh
    

    当然,这取决于屏幕,如果您需要标准输入或标准输出,您可以稍后附加。当 my-script.sh 结束时,屏幕将自行终止。

    【讨论】:

      【解决方案5】:

      下面是一个更常见的决定,需要一些努力才能找到,它确实对我有用:

      #!/usr/bin/bash
      theScreenSessionName="test"
      theTabNumber="1"
      theStuff="date; hostname; cd /usr/local; pwd; /usr/local/bin/top"
      
      echo "this is a test"
      
      ssh -f user@server "/usr/local/bin/screen -x $theScreenSessionName -p $theTabNumber -X stuff \" 
      $theStuff
      \""
      

      它发送 $theStuff 命令列表到选项卡 No $theTabNumber 屏幕会话 $theScreenSessionName 代表“用户”在“服务器”初步创建。

      请注意后面的空格 -X 东西\" 这是为了克服“东西”选项的故障而发送的。下一行中的空格和 $theStuff 由 'Enter' (^M) 击键附加。不要错过他们!

      “这是一个测试”消息在初始终端中回显,并且 $theStuff 命令真正在提到的屏幕/选项卡内执行。

      【讨论】:

        猜你喜欢
        • 2010-12-21
        • 2012-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-24
        • 2017-08-13
        • 2021-03-01
        • 1970-01-01
        相关资源
        最近更新 更多