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?
-
If you're into `screen`, consider trying [tmux](http://tmux.sourceforge.net/). Lot of differences, but it's worth the switch. – jpaugh Feb 19 '14 at 01:14
-
I primarily use screen for its daemon-like capabilities, for lack of a better alternative. If tmux is as cooperative with CLIs as screen (Allowing, for example, injection of commands into a running screen via bash) then I may indeed switch. – Zoey Feb 19 '14 at 02:07
-
1this thread is brilliant and perfect for my use case... I had been mucking around with pgrep and pkill, but -Q and -X are great for a daemonized process check. I don't agree with the selected answer... grepping in this case has many potential pitfalls. – Eyelash Jul 17 '16 at 21:57
-
Possible duplicate of [How to list running screen sessions?](https://stackoverflow.com/q/537942/608639) – jww Sep 19 '19 at 17:51
-
definitely NOT a duplicate. Also thank you so much for an awesome question. I learned so much! For anyone else: Please see my comments below regarding checking for sessions by other users as is often the case when you need to make sure someone else isn't currently running your script already. – Hicsy Mar 31 '20 at 08:38
6 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

- 497,756
- 71
- 530
- 681
-
5Of course, but is it possible to check it without using `grep`? i.e. a screen command. In case you want to know if session "abcd" exists but there is only session "abcdefgh" your condition will say yes while it's actually no. – e271p314 Feb 11 '14 at 17:31
-
2You can modify the `grep` command. `grep -q '^abcd$'` would match only the exact session name 'abcd'. – chepner Feb 11 '14 at 17:48
-
4Still looks like it won't work since "^abcd$" is a regular expression matching lines which contain only "abcd". Your answer is ok. My question was, does screen support the functionality of returning 0 if a session with specific name exists and not 0 otherwise – e271p314 Feb 11 '14 at 17:55
-
while I REALLY like the idea of `-Q select myWindow` (also checks for specific window)... this grep method was the easiest check for sessions by other users: `if (screen -ls user/ | grep -q '\.mySession\s');` – Hicsy Mar 31 '20 at 08:49
-
Works perfect In combination with cron that checks a specified screen in a script – AxelS Nov 14 '22 at 05:00
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.

- 2,388
- 2
- 15
- 14
-
1Is there a doc on what the -Q parameter does? My version of Screen (Ubuntu 12) does not seem to have it, which makes me wonder if this is non-standard or has a different alias on different builds. – Namey Sep 04 '14 at 01:49
-
Even the man page of screen on Debian doesn't mention it, it does work. – mehulved Feb 10 '15 at 13:19
-
Hmm, on Fedora 22, using screen 4.03.01, the man page does mention the Q command and the commands that can be queried. I'm not sure where I found the tidbit about the '.' in the select statement ... – troyfolger Sep 10 '15 at 17:30
-
For me `screen -S Tomcat -Q echo ''; echo $?` also works but triggers no redraw. – Lars Schillingmann Nov 17 '17 at 00:32
-
It works for me on one system (screen version 4.03.01) and not on another (4.00.03). – Digicrat Dec 13 '17 at 23:27
-
Can also redirect noise: `if (screen -S user/session -Q select myWindow > /dev/null);` .... interestingly: `-Q` lets you check for a specific window, where `-X select myWindow` ALWAYS behaves as if you wrote `-X select .` regardless of sub-windows. Also interesting: These methods also inherently validate permissions on multi-user sessions, unlike `-ls | grep`. – Hicsy Mar 31 '20 at 08:30
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.

- 267
- 3
- 12
-
Hmm ... I'm sticking with -Q! :^] It may be due to differences in versions of screen. I think older versions of screen didn't have the Q (query) option, so you had to resort to using the X option (send command to screen). Here's the relevant info from the man page for screen 4.03.01: -Q Some commands now can be queried from a remote session using this flag, e.g. "screen -Q windows". The commands will send the response to the stdout of the querying process. If there was an error in the command, then the querying process will exit with a non-zero status. – troyfolger Sep 10 '15 at 17:36
-
I won't downvote, but you might amend your answer to "older versions of screen require 'X' instead of 'Q' ..." – troyfolger Sep 10 '15 at 17:37
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.

- 9,342
- 4
- 39
- 59
-
1A simpler solution if screen -ls TEST|grep -q '\.TEST\s'; then echo "TEST exists"; fi – Ramast Dec 29 '15 at 12:08
a simpler method is :
screen -xR -S SessionName
copied from a Stéphane Chazelas comment from here:
I generally use -xR to attach or create if there's nothing to attach.
so like that you do not have to search if the session name already exist, this method will attach to the session if it exist and if not then it will creat it.

- 1,487
- 14
- 20
%100 Work.
screen -list | grep "SESSİON NAME" && echo "Active Program" || echo "Passive Program"

- 50,871
- 7
- 38
- 64

- 11
- 1