我制作了一个 bash 文件,它在分离的屏幕中启动另一个具有唯一名称的 bash 文件,我需要确保该内部 bash 文件的一个实例在任何一个时间点都在运行。为此,我想让父 bash 文件检查该名称的屏幕是否存在,然后再尝试创建它。有没有办法做到这一点?
6 回答
您可以 grep 的输出来screen -list
查找您正在检查的会话的名称:
if ! screen -list | grep -q "myscreen"; then
# run bash script
fi
您可以查询特定会话的屏幕“选择”命令;如果会话存在,shell 结果为“0”,如果未找到命名的屏幕会话,则为“1”:
$屏幕-S Tomcat $ 屏幕 -S Tomcat -Q 选择 . ; 回声$? 0
相对:
$ 屏幕 -S 码头 -Q 选择。; 回声$? 未找到屏幕会话。 1
请注意,'.'
后面select
是可选的,但可能更健壮。
鉴于我无法发表评论,我将其发布为新答案。troyfolger 的回答是一个好主意,基本上相当于尝试向会话发送一个几乎没有什么作用的命令。一个问题是某些(旧)版本的 screen -Q 不受支持,因此对于这些版本,正确的命令是
screen -S Jetty -X select . ; echo $?
其中发送命令“选择”。到名为“Jetty”的屏幕会话。
选择更改哪个窗口处于活动状态和 。表示当前活动窗口,因此这意味着尝试将活动窗口更改为当前活动窗口。如果没有会话可以连接到我们想要的会话,这只会失败。
如果您阅读信息文档,那么它确实建议您只使用 select 。与 -X 作为测试或确保选择了某些东西。
一个更简单的方法是:
screen -xR -S SessionName
从这里的Stéphane Chazelas评论中复制:
如果没有要附加的内容,我通常使用 -xR 附加或创建。
因此,您不必搜索会话名称是否已经存在,如果会话存在,此方法将附加到会话,如果不存在,则创建它。
所有提出的解决方案都不处理没有唯一模式的屏幕名称,例如“TEST”和“TEST123”。当您screen -S "TEST"
或screen -list "TEST"
时,您可能会发现自己正在选择屏幕“TEST123”!GNU 屏幕如何实现屏幕名称匹配存在一些错误(非确定性)。
下面是一个 bash 函数,它尝试进行完全匹配,并返回PID.SCREEN NAME
退出代码:
function find_screen {
if screen -ls "$1" | grep -o "^\s*[0-9]*\.$1[ "$'\t'"](" --color=NEVER -m 1 | grep -oh "[0-9]*\.$1" --color=NEVER -m 1 -q >/dev/null; then
screen -ls "$1" | grep -o "^\s*[0-9]*\.$1[ "$'\t'"](" --color=NEVER -m 1 | grep -oh "[0-9]*\.$1" --color=NEVER -m 1 2>/dev/null
return 0
else
echo "$1"
return 1
fi
}
用法 - 选择一个屏幕:
target_screen=$(find_screen "SCREEN NAME")
screen -S "$target_screen" ...etc...
用法 - 测试屏幕是否存在:
if find_screen "SCREEN NAME" >/dev/null; then
echo "Found!"
fi
无论如何,这将涵盖 99.9% 的情况。99,99% 确定,在屏幕名称中转义 grep 特殊字符。完美匹配需要 grep 匹配整行直到 $,包括括号中的日期,可能会随着版本的变化而变化。另一种完美匹配方法是:
ls -A -1 /var/run/screen/S-${USER} | grep "^[0-9]*\.SCREEN NAME$"
但这很麻烦,我们需要确保屏幕实现使用这个文件夹。我不推荐最后一种方法。
%100 工作。
screen -list | grep "SESSİON NAME" && echo "Active Program" || echo "Passive Program"