如何在不使用 -f 的情况下让 ssh 在后台运行?

如何在不使用 -f 的情况下让 ssh 在后台运行?

我正在尝试创建一个 ssh 隧道,将其转入后台进程,并编写一个 pid 文件,稍后可以使用它来终止它。我可以使用 运行 ssh -f,但我无法控制它的 PID。

但是,当我尝试通过 nohup 或 setsid 运行下面的脚本时,控制权永远不会返回到我尝试守护该脚本的 shell。

#!/bin/sh                                                 

while getopts ":v" flag; do
    case $flag in
        v|verbose) verbose=1;;
        :) echo "option -$lastflag requires an argument"; exit 1;;
    esac 
    lastflag="$flag"
    shift $((OPTIND - 1)); OPTIND=1
done

ssh  -p '2222'  -nNL '5984:localhost:5984' '[email protected]' &
pid=$!
sleep 2;
ps -p $pid >/dev/null 2>&1 || exit 1
echo $pid > "var/couchdb-tunnel.pid"
wait

调用:

nohup script.sh
setsid script.sh

我该如何说服 ssh(我假设)放弃终端?还有其他方法可以实现我想要的吗?

答案1

您正在寻找的 shell 内置命令是disown,它将后台作业重新设置为 ,init以便脚本可以退出并安全地将它们留在后台。您可能希望将输出重定向到/dev/null(或日志文件),以避免在启动脚本后在 shell 中获取输出。

ssh hostname 'command' &>/dev/null &
disown

答案2

这不会wait导致你的脚本等待吗?从手册页...

wait [n ...] 等待每个指定的进程并返回其终止状态。每个 n 可以是进程 ID 或作业规范;如果给出了作业规范,则等待该作业管道中的所有进程。 如果没有给出 n,则等待所有当前活动的子进程,并且返回状态为零。 如果 n 指定不存在的进程或作业,则返回状态为 127。否则,返回状态是等待的最后一个进程或作业的退出状态。

因此,您的脚本正在等待 ssh 隧道完成后再返回提示。只需删除wait,您就会收到提示,并且您的隧道将在后台运行。

答案3

我习惯screen在同一个终端窗口中运行不同的连接和脚本。这样我就可以关闭机器,回家后再打开机器并重新加载screen我想要监视正在发生的事情的会话。

当然,这是假设我从我的终端通过 SSH 连接到另一台机器。

相关内容