我正在尝试创建一个 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 连接到另一台机器。