Home » Linux » Checking if a Screen of the Specified Name Exists

Checking if a Screen of the Specified Name Exists

Posted by: admin November 29, 2017 Leave a comment

Questions:

I have made a bash file which launches another bash file in a detached screen with a unique name, I need to ensure that only one instance of that internal bash file is running at any one point in time. To do this, I want to make the parent bash file check to see if the screen by that name exists before attempting to create it. Is there a method to do this?

Answers:

You can grep the output of screen -list for the name of the session you are checking for:

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

Questions:
Answers:

You can query the screen ‘select’ command for a particular session; the shell result is ‘0’ if the session exists, and ‘1’ if the named screen session is not found:

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

versus:

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

Note that the '.' after the select is optional, but may be more robust.

Questions:
Answers:

Given I can’t comment I am posting this as a new answer. troyfolger’s answer is a good idea and basically amounts to try and send the session a command that will do very little. One issue is that for some (older) versions of screen -Q isn’t supported and so for those versions the correct command is

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

Which send the command “select .” to the screen session called “Jetty”.

Select changes which window is active and . means the current active window so this means try and change the active window to the currently active window. This can only fail if there isn’t a session to connect to which is what we wanted.

If you read the info docs than it does suggest that the only use of select . is with -X as a test or to make sure something is selected.

Questions:
Answers:

All the solutions proposed don’t deal with screen names that don’t have unique patterns, e.g. “TEST” and “TEST123”. When you screen -S "TEST" or screen -list "TEST", you may find yourself selecting the screen “TEST123”! There is something wrong (non-deterministic) in how GNU screen implements screen name matching.

Below is a bash function that tries to do exact matches, and return the PID.SCREEN NAME along with an exit code:

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
}

Usage – select a screen:

target_screen=$(find_screen "SCREEN NAME")
screen -S "$target_screen" ...etc...

Usage – test if a screen exists:

if find_screen "SCREEN NAME" >/dev/null; then
    echo "Found!"
fi

Anyway, this will cover 99,9% cases. To be 99,99% sure, escape grep special chars in the screen name. A perfect match would require grep to match the whole line until $, including the date in parenthesis that may evolve with versions. The other perfect match method would be:

ls -A -1 /var/run/screen/S-${USER} | grep "^[0-9]*\.SCREEN NAME$"

But that’s hacky, and we need to be sure that screen implementation uses this folder. I don’t recommend this last method.

Questions:
Answers:

%100 Work.

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