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

时间:2012-09-04 00:28:04

标签: linux bash gnu-screen

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

6 个答案:

答案 0 :(得分:27)

您可以将screen -list的输出格式化为您要检查的会话名称:

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

答案 1 :(得分:16)

您可以查询特定会话的屏幕'select'命令;如果会话存在,则shell结果为“0”;如果未找到指定的屏幕会话,则结果为“1”:


$ screen -S Tomcat
$ screen -S Tomcat -Q select . ; echo $?
0


$ screen -S Jetty -Q select . ; echo $?
No screen session found.
1

请注意'.'之后的select是可选的,但可能更强大。

答案 2 :(得分:8)

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

screen -S Jetty -X select . ; echo $?

发送命令"选择。"到了#34; Jetty"的屏幕会话。

选择更改哪个窗口处于活动状态。表示当前活动窗口,因此这意味着尝试将活动窗口更改为当前活动窗口。只有在没有会话连接到我们想要的地方时,这才会失败。

如果您阅读的信息文档比它建议的唯一使用选择。使用-X作为测试或确保选择某些内容。

答案 3 :(得分:2)

所提出的所有解决方案都不涉及没有独特模式的屏幕名称,例如: “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$"

但这很麻烦,我们需要确保屏幕实现使用此文件夹。我不推荐这最后一种方法。

答案 4 :(得分:0)

%100工作。

screen -list | grep "SESSİON NAME" && echo "Active Program" || echo "Passive Program"

答案 5 :(得分:0)

一个更简单的方法是:

screen -xR -S SessionName

hereStéphaneChazelas 评论中复制:

  

我通常使用-xR附加或创建没有附加内容的东西。

像这样,您不必搜索会话名称是否已存在,该方法将附加到会话(如果存在),否则将创建它。