运行脚本并在 SSH 断开连接(如管道损坏)后使其处于活动状态,而无需在后台强制它
Posted
技术标签:
【中文标题】运行脚本并在 SSH 断开连接(如管道损坏)后使其处于活动状态,而无需在后台强制它【英文标题】:Running a script and get it alive after a SSH disconnection (like a broken pipe) without forcing it in background 【发布时间】:2022-01-21 18:24:41 【问题描述】:如果我有一个类似这样的 bash 脚本
#!/bin/bash -p
echo "PART A PID $$" >> "txt$$.txt";
for ((a=1; a<=10; a++))
do
sleep 1
echo "PART B$a" >> "txt$$.txt";
done
echo "PART C" >> "txt$$.txt";
我知道./script.sh & disown
可以防止脚本在 SSH 退出时停止,但我想在不需要将脚本置于后台的情况下实现这一点。
PART A
PART B1
PART B2
PART B3
PART B4
PART B5
PART B6
PART B7
PART B8
PART B9
PART B10
PART C
并得到这样的输出。
我想等待循环得到一个有序的输出。
注意(我不想要 nohup)
编辑
我这样做是因为我想开始不止一个。
如果我做类似的事情
#!/bin/bash -p
(
echo "PART A PID $$" >> "txt$$.txt";
for ((a=1; a<=10; a++))
do
sleep 1
echo "PART B$a" >> "txt$$.txt";
done
echo "PART C" >> "txt$$.txt";
) & disown
PID 发生变化。这样,如果我想停止该进程,我将无法获取 pid 的原始引用。
我想知道是否有一些简单的东西可以放在底部,而不会打乱所有代码
【问题讨论】:
听起来您想为脚本实现一些自动后台逻辑,尽管您的“我想等待”似乎与此相矛盾。你试过什么? "听起来你想为脚本实现一些自动后台逻辑,虽然你的'我想等待'似乎与此相矛盾。你试过什么?"没有。我不知道该怎么做。我在for之后只添加了done & disown
,但是这样不尊重输出顺序。
双叉(改变 PID)是如何完成自后台/守护进程,即使在 C 中也是如此。
从父进程中“拒绝”进程是将其从由父 shell 跟踪的作业表中删除。该表(与操作系统的进程表不同)是父 shell 进程状态的一部分,存储在该父 shell 的内存中。它不是整个操作系统控制的东西,因此不是一个单独的进程有能力直接进入和修改的东西。
顺便说一句,在程序中多次放入>> "txt$$.txt"
是一种不好的形式——每次进行重定向时,它都会重新打开输出文件。考虑将exec >"txt$$.txt"
放在脚本顶部一次;这将使 all 未来的标准输出转到指定的文件。
【参考方案1】:
正如您在 cmets 中解释的那样,您的真正目标是让您的脚本在默认情况下仍然在前台运行,但要确保它在 SSH 断开连接后仍然存在。
您可以在不需要disown
的情况下以任何方式执行此操作,但代码需要放在顶部,而不是底部:
#!/usr/bin/env bash
# redirect all three of stdin, stdout and stderr (not just stdout!)
exec >"txt$$.txt" 2>"err$$.txt" </dev/null
# ignore any SIGHUP signals received
trap : SIGHUP
# ...put the content of your script here
【讨论】:
\\\\///// 啊。好的。我不知道trap : SIGHUP
它是不被召回的。而且我也不知道exec >"txt$$.txt" 2>"err$$.txt" </dev/null
完成了所有工作。最佳答案 4 u ?? HIIIIIIIIIIIIIII ?以上是关于运行脚本并在 SSH 断开连接(如管道损坏)后使其处于活动状态,而无需在后台强制它的主要内容,如果未能解决你的问题,请参考以下文章
(统一)销毁当前场景中的游戏对象并在加载当前场景后使其永久销毁?
从损坏的管道读取时,管道 Python 脚本占用 100% 的 CPU