Linux 检查指定名称的屏幕是否存在

Linux 检查指定名称的屏幕是否存在,linux,bash,gnu-screen,Linux,Bash,Gnu Screen,我制作了一个bash文件,它在一个分离的屏幕中启动另一个具有唯一名称的bash文件,我需要确保在任何一个时间点上只运行该内部bash文件的一个实例。要做到这一点,我希望在尝试创建它之前,检查父bash文件,以查看该名称的屏幕是否存在。有什么方法可以做到这一点吗?您可以在屏幕列表的输出中搜索您要检查的会话的名称: if ! screen -list | grep -q "myscreen"; then # run bash script fi 您可以查询特定会话的屏幕“选择”命令;如果会

我制作了一个bash文件,它在一个分离的屏幕中启动另一个具有唯一名称的bash文件,我需要确保在任何一个时间点上只运行该内部bash文件的一个实例。要做到这一点,我希望在尝试创建它之前,检查父bash文件,以查看该名称的屏幕是否存在。有什么方法可以做到这一点吗?

您可以在
屏幕列表的输出中搜索您要检查的会话的名称:

if ! screen -list | grep -q "myscreen"; then
    # run bash script
fi

您可以查询特定会话的屏幕“选择”命令;如果会话存在,则外壳程序结果为“0”;如果找不到指定的屏幕会话,则外壳程序结果为“1”:

$ screen -S Tomcat $ screen -S Tomcat -Q select . ; echo $? 0 $screen-S Tomcat $screen-S Tomcat-Q选择;回声$? 0 与:

$ screen -S Jetty -Q select . ; echo $? No screen session found. 1 $screen-S Jetty-Q选择;回声$? 找不到屏幕会话。 1.
请注意,
选择之后的
是可选的,但可能更可靠。

鉴于我无法发表评论,我将此作为新答案发布。troyfolger的回答是一个好主意,基本上相当于尝试向会话发送一个命令,但效果甚微。一个问题是,对于screen-Q的某些(较旧)版本不受支持,因此对于这些版本,正确的命令是

screen -S Jetty -X select . ; echo $?
将“选择”命令发送到名为“Jetty”的屏幕会话

选择更改哪个窗口处于活动状态,然后单击“更改”。表示当前活动窗口,因此这意味着尝试将活动窗口更改为当前活动窗口。如果没有我们想要连接的会话,这只能失败


如果您阅读了信息文档,则建议只使用select。使用-X作为测试或确保选择了某些内容。

所有建议的解决方案都不处理没有唯一模式的屏幕名称,例如“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"
更简单的方法是:

screen -xR -S SessionName
抄袭自Stéphane Chazelas的评论,来自:

如果没有要附加的内容,我通常使用-xR来附加或创建


因此,您不必搜索会话名称是否已存在,如果会话名称已存在,此方法将附加到该会话,如果不存在,则将创建该会话。

当然可以,但是否可以在不使用
grep
的情况下对其进行检查?i、 e.屏幕命令。如果您想知道会话“abcd”是否存在,但只有会话“abcdefgh”,则您的条件会说是,而实际上是否。您可以修改
grep
命令<代码>grep-q“^abcd$”
将仅与确切的会话名称“abcd”匹配。由于“^abcd$”是一个正则表达式,仅与包含“abcd”的行匹配,因此它看起来仍然无法工作。你的回答是可以的。我的问题是,如果存在具有特定名称的会话,屏幕是否支持返回0的功能,而不是以其他方式返回0,而我非常喜欢
-Q select myWindow
(还检查特定窗口)。。。这个grep方法是其他用户检查会话最简单的方法:
if(screen-ls-user/|grep-q'\.mySession\s')如果你进入<代码>屏幕<代码>,请考虑尝试。有很多不同之处,但值得一试。我主要使用screen的守护程序功能,因为没有更好的替代方案。如果tmux像screen一样与CLIs合作(例如,允许通过bash将命令注入正在运行的屏幕),那么我确实可以切换。这个线程非常出色,非常适合我的用例。。。我一直在玩弄pgrep和pkill,但是-Q和-X对于后台进程检查来说非常好。我不同意选择的答案。。。在这种情况下,grepping有许多潜在的陷阱。可能的重复肯定不是重复。也非常感谢你提出了一个很棒的问题。我学到了很多!对于其他人:请参阅下面我关于检查其他用户会话的评论,通常情况下,当您需要确保其他人当前没有运行您的脚本时也是如此。是否有关于-Q参数作用的文档?我的Screen版本(Ubuntu12)似乎没有,这让我想知道这是不是非标准的,或者在不同的版本上有不同的别名。即使Debian上Screen的手册页没有提到它,它也能工作。嗯,在Fedora22上,使用Screen 4.03.01,手册页提到了Q命令和可以查询的命令。我不确定在select语句中哪里找到了有关“.”的小道消息……对我来说
screen-S Tomcat-Q echo';echo$?
也可以工作,但不会触发重画。它在一个系统(屏幕版本4.03.01)上对我有效,而在另一个系统(4.00.03)上无效。嗯。。。我坚持-Q!:^]这可能是由于屏幕版本不同造成的。我认为旧版本的screen没有Q(查询)选项,所以您必须使用X选项(向screen发送命令)。以下是屏幕4.03.01的手册页中的相关信息:-Q现在可以使用此标志从远程会话中查询某些命令,例如“屏幕-Q窗口”。这些命令将向查询进程的stdout发送响应。如果命令中有错误,则查询进程将以n退出