【问题标题】:running ssh process in background gets paused在后台运行 ssh 进程被暂停
【发布时间】:2016-03-27 10:36:57
【问题描述】:

我有一些脚本正在 vm 上开发,但有时需要在生产服务器上运行才能正确测试。

我需要脚本的输出进行调试,因此我将以下解决方案组合在一起:

function test_remote() {
    scp $1 Prod:/home/xxx/tmp/
    n=${1:t:r}
    f=${1:t}
    cmd="ssh Prod \"/usr/bin/php /home/xxx/tmp/$f\" > /home/xxx/tests/$n-remote-test.html"
    eval ${cmd}
    ssh Prod "rm /home/xxx/tmp/$f"
    echo "done"
}

我已放在我的 .zshrc 文件中

我想使用

在后台运行它
test_remote path_to_file/php_file.php &

但我总是得到以下结果

[1]  + 12996 suspended (tty input)  test_remote path_to_file/php_file.php

如果我用 bg 恢复它,它只会重复相同的消息

【问题讨论】:

  • 在调用test_remotecmd 时使用</dev/null 重定向stdin 是否有效?
  • 在这两种情况下都可以!如果您不介意,最好在帖子中进行一些解释,以便我可以将其标记为正确答案

标签: shell ssh terminal zsh


【解决方案1】:

SSH 正在从其标准输入(即终端)读取。即使远程端的程序不尝试从其标准输入中读取,它也会这样做,因为它无法知道远程端不会尝试(也因为用户可以按下诸如 Ctrl+C 服务器端将转换为发送信号)。

明智地只能从终端读取一个进程:如果有多个进程,哪个进程会收到每个按键? (当确实发生时,效果是每个字节或多或少随机地传送到不同的进程。)内核中的终端管理框架确保(在正常情况下)只有前台进程接收终端输入。如果后台进程试图从终端读取,它会收到一个 SIGTTIN 信号,并且该信号的默认操作是挂起该进程。 “12996 suspend (tty input)”是让你知道进程 12996 被 SIGTTIN 挂起的 shell。

对于任何可能尝试从其标准输入读取的后台命令,避免这种情况的通用方法是将其标准输入从其他地方重定向,例如/dev/null

mycommand </dev/null &

使用 SSH 客户端,您可以使用-n 选项来达到相同的效果。您也可以使用-f 选项告诉ssh 在读取密码后进入后台;如果您必须使用密码,这很有用,但您应该尽可能使用密钥。这些选项的缺点是后台进程不是 shell 作业,因此您不能等待其终止并获取。


你到底为什么要使用eval?随便写

ssh Prod "/usr/bin/php /home/xxx/tmp/$f" > /home/xxx/tests/$n-remote-test.html

【讨论】:

    【解决方案2】:

    当后台进程尝试从标准输入读取数据时,它会收到一个暂停它的信号。这样用户就可以再次将进程带到前台并提供必要的输入。

    如果不需要提供输入,您可以在调用test_remotecmd 时从/dev/null 重定向标准输入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-30
      • 2023-03-29
      • 1970-01-01
      • 2019-01-11
      • 2020-02-02
      • 1970-01-01
      • 2012-02-26
      • 1970-01-01
      相关资源
      最近更新 更多