仅当屏幕会话不存在时才在后台创建它

仅当屏幕会话不存在时才在后台创建它

screen如果不存在,我怎样才能创建一个分离模式?

这将以分离模式创建一个名为 name 的屏幕,但会创建重复项

screen -dmS name command

仅当屏幕不存在时才会创建屏幕,但不会分离

screen -dRms name command

我该如何将两者结合起来?我需要在批处理文件中创建多个屏幕,因此重新连接并不方便。我想使用批处理文件“重新启动”由于各种原因而死机的屏幕,但保持已经运行的屏幕完好无损。

答案1

我刚刚偶然发现了这个问题并这样解决:

  1. 创建一个 Python 脚本来检查屏幕会话是否存在。
  2. 一些 shell 脚本

就我而言,我感兴趣的屏幕会话名称是'activity'(对于我的活动追踪器项目)。

Python 脚本does_screen_session_exist.py

Python 3.4+;无依赖项:

#!/usr/bin/env python

"""
Check if a screen session exists.

If it does, give exit code 0.
If it doesn't, give exit code 1.
"""

import subprocess
import sys
from argparse import ArgumentParser
from typing import List

parser = ArgumentParser()
parser.add_argument("session_name")


def main(session_name: str) -> None:
    session_names = get_active_screen_sessions()
    if session_name in session_names:
        print(f"Screen session '{session_name}' exists")
        sys.exit(0)
    else:
        print(f"Screen session '{session_name}' does NOT exist")
        sys.exit(1)


def get_active_screen_sessions() -> List[str]:
    result = subprocess.run(["screen", "-ls"], stdout=subprocess.PIPE)
    output = result.stdout.decode("utf-8")
    if "No Sockets found" in output:
        return []
    assert "There is a screen on" in output

    # get lines
    lines = []
    for line in output.splitlines():
        if line.startswith("\t"):
            lines.append(line)

    # get session names
    session_names = []
    for line in lines:
        line = line.strip()
        line = line.split("\t")[0]
        line = line.split(".")[1]
        session_names.append(line)
    return session_names


if __name__ == "__main__":
    args = parser.parse_args()
    main(args.session_name)

Bash 脚本

python does_screen_session_exist.py activity
status=$?
if [ $status = 0 ]
then
    echo 'activity' screen exists
else
    echo Start activity screen
    screen -S activity -U -d -m activity_tracker log-activity
fi

答案2

最简单的单行解决方案是使用带有屏幕的 flock:

尝试这个:

screen -S session-name -d -m flock -n /tmp/some_lockfile sleep 100
screen -S session-name -d -m flock -n /tmp/some_lockfile sleep 100
screen -ls

它将仅列出一个会话。希望这会有所帮助。

答案3

谢谢你的解决方案。如果有人需要,可以使用更紧凑的 Python 函数:

async def check_screen_exists(screen_name: str):
    proc = await asyncio.create_subprocess_shell("screen -ls", stdout=asyncio.subprocess.PIPE)
    stdout,stderr = await proc.communicate()
    existed_screens = [line.split(".")[1].split("\t")[0].rstrip() for line in stdout.decode("utf-8").splitlines() if line.startswith("\t")]
    if screen_name in existed_screens:
        return True

相关内容