运行 后台 ssh 进程暂停
running ssh process in background gets paused
我有一些正在虚拟机上开发的脚本,但有时需要 运行 在生产服务器上进行正确测试。
我需要脚本的输出进行调试,所以我整理了以下解决方案:
function test_remote() {
scp 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_remote
时或在 cmd
.
中重定向来自 /dev/null
的标准输入
SSH 正在从其标准输入(即终端)读取数据。即使远程端的程序不尝试从其标准输入读取,它也会这样做,因为它无法知道远程端不会尝试(也因为用户可以按 Ctrl+C 服务器端将转换为发送信号)。
只能有一个进程从终端读取数据:如果有多个进程,哪个进程会接收到每个按键? (当 确实 发生时,效果是每个字节或多或少随机地进入不同的进程。)内核中的终端管理框架确保(在正常情况下)只有前台进程接收终端输入。如果后台进程试图从终端读取,它会收到一个 SIGTTIN 信号,该信号的默认操作是挂起该进程。 “12996 暂停(tty 输入)”是 shell 让您知道进程 12996 已被 SIGTTIN 暂停。
避免这种情况的通用方法是,使用任何可能尝试从其标准输入读取的后台命令,将其标准输入重定向到其他地方,例如 /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
我有一些正在虚拟机上开发的脚本,但有时需要 运行 在生产服务器上进行正确测试。
我需要脚本的输出进行调试,所以我整理了以下解决方案:
function test_remote() {
scp 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_remote
时或在 cmd
.
/dev/null
的标准输入
SSH 正在从其标准输入(即终端)读取数据。即使远程端的程序不尝试从其标准输入读取,它也会这样做,因为它无法知道远程端不会尝试(也因为用户可以按 Ctrl+C 服务器端将转换为发送信号)。
只能有一个进程从终端读取数据:如果有多个进程,哪个进程会接收到每个按键? (当 确实 发生时,效果是每个字节或多或少随机地进入不同的进程。)内核中的终端管理框架确保(在正常情况下)只有前台进程接收终端输入。如果后台进程试图从终端读取,它会收到一个 SIGTTIN 信号,该信号的默认操作是挂起该进程。 “12996 暂停(tty 输入)”是 shell 让您知道进程 12996 已被 SIGTTIN 暂停。
避免这种情况的通用方法是,使用任何可能尝试从其标准输入读取的后台命令,将其标准输入重定向到其他地方,例如 /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