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?
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
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.
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.
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.
%100 Work.
screen -list | grep "SESSİON NAME" && echo "Active Program" || echo "Passive Program"
来源:https://stackoverflow.com/questions/12255388/checking-if-a-screen-of-the-specified-name-exists