How to check in If-Statement if a screen is already running - linux

I want to write a bash script where I check If my Screen (I gave this screen the name a3_altis) is already running or not, just like this:
if (screen a3_altis is running)
then
./stop.sh
sleep 5
./start.sh
else
./start.sh
fi
I'm new in Bash, so I don't really know how to check If a screen is running.

screen may provide a more robust mechanism, but it should suffice to just use grep:
if screen -ls | grep -q a3_altis; then
./stop.sh
sleep 5
fi
./start.sh

Related

Keep attached screen session alive and waiting for more commands to enter from detached screens

I had this idea of a script that I was trying to make come to light. I want one main process that is running and keeping track of subprocesses running in the background. I decided to go with screen for my implementation, and I can run the main.sh in attached mode, with the subcommands all running in detached. I can also send text to the main.sh once each sub-process has hit their point. However, i want the main script to be running until all sub-processes finish (accomplished), but I want it to be updating what it is printing out to the user. I currently have the main process doing:
while screen -list | grep -q process-1 || screen -list | grep -q process-2 || screen -list | grep -q process-3; do
sleep 1
done
which works perfectly as the main loop, but any data i send to that process just prints out like text, not like a command. Is there a way I can keep a screen session alive and receiving more commands/variables?
I currently plan on sending data from the sub-process like screen -S main -X stuff "PROCESS_1=FINISHED" and the main will keep trying to grab the variable PROCESS_1 to get it's status.
I can't just get the result of the sub-process either, as for at least one of the commands i plan on it running continuously, but I want to let the main-process know when it has hit a certain point. I was also tinkering with the idea of using file descriptors but I had issues getting that working in detached mode.
Is this possible and I haven't just used/found the right command? Do i need to somehow use another screen as a like a data layer so that the main layer just prints out to the user?
For completeness, here is the current setup:
start.sh
#!/bin/bash
screen -S process-1 -dm ./process-1.sh
screen -S process-2 -dm ./process-2.sh
screen -S main -m ./main.sh
main.sh
#!/bin/bash
while screen -list | grep -q process-1 || screen -list | grep -q process-2; do
sleep 1
done
process-1.sh
#!/bin/bash
count=0
while [[ count -ne 5 ]]; do
((count+=1))
sleep 5
done
screen -S main -X stuff "PROCESS_1=FINISHED"
process-2.sh
#!/bin/bash
count=0
while [[ count -ne 3 ]]; do
((count+=1))
sleep 5
done
screen -S main -X stuff "PROCESS_2=FINISHED"
Thanks for any advice you can provide.
EDIT:
Something along these lines is the end goal, like Vue.js, a constant screen that updates whenever changes are made (or in this case processes end)

How can I determine if my KDE Desktop is in lock screen state from command line?

I have a program run on the background that simply take a screenshot every N seconds.
eg:
#!/bin/sh
while true; do
take-screenshot
sleep 10
done
What I want to achieve is only take screenshot if screen is not locking.
eg:
#!/bin/sh
while true; do
if ! screen-is-locking; then
take-screenshot
sleep 10
fi
done
How can I determine if my desktop is locking in command line?
According to this link provided by fellow comments under this question, I got a solution or workaround for my question, it works well under 5.4.58-1-MANJARO KDE Plasma (other DE might have different ways according to that answer's statement).
There's a method in dbus service which well fit my need:
#/bin/sh
is_screen_locking()
{
if dbus-send --session --dest=org.freedesktop.ScreenSaver --type=method_call --print-reply /org/freedesktop/ScreenSaver org.freedesktop.ScreenSaver.GetActive | grep 'boolean true' > /dev/null; then
return 0
else
return 1
fi
}
if is_screen_locking; then
echo 'screen is locking'
else
echo 'screen is not locking'
fi

How can we prevent CTRL-C from screen terminating?

I'm currently writing a bash script that would create multiple shell instances (with screen command) and execute a subprogram.
The problem is when I try to interrupt the subprogram, it interrupts the screen instance too. I already searched for trap command on internet with SIGINT but I don't really know how to use it in this case.
Here is my code to show you how do I create the screen:
#!/bin/bash
#ALL PATHS ARE DECLARED HERE.
declare -A PATHS; declare -a orders;
PATHS["proxy"]=/home/luna/proxy/HydraProxy; orders+=( "proxy" )
PATHS["bot"]=/home/luna/bot; orders+=( "bot" )
#LAUNCH SERVERS
SERVERS=/home/luna/servers
cd "$SERVERS"
for dir in */; do
d=$(basename "$dir")
PATHS["$d"]="$(realpath $dir)"; orders+=( "$d" )
done
for name in "${orders[#]}"; do
if ! screen -list | grep -q "$name"; then
path="${PATHS[$name]}"
cd "$path"
screen -dmS "$name" ./start.sh
echo "$name CREATED AT $path"
sleep 2
else
echo "SCREEN $name IS ALREADY CREATED"
fi
done
Could you help me more to find a solution please ? Thank you very much for your time.
Each of your screen instances is created to run a single command, start.sh. When this command terminates, for instance when you interrupt it, the screen will have done its job and terminate. The reason for this is that screen runs shell scripts directly in a non-interactive shell, rather than spawning a new interactive shell and running it there.
If you wanted to run start.sh inside an interactive shell in each screen, you'd do something like this:
screen -dmS "$name" /bin/bash -i
screen -S "$name" -X stuff "./start.sh^M"
The ^M is needed as it simulates pressing enter in your shell within screen.
If you use this, then when you interrupt a script within screen, you will still be left with an interactive prompt afterward to deal with as you see fit.

How to detect if i3-wm is being run or GNOME is being run in bash

I've been using i3-wm for about six months now, and I had to switch to GNOME because Discord was crashing a lot in i3. I had previously used the i3-msg command in my bashrc to make sure the borders of the terminal wouldn't be visible, as to use the entire screen space for the terminal. The specific command I run is:
i3-msg -q border toggle
The problem is, when I use GNOME and I open up a terminal, the i3-msg command runs, and causes an error message evidently caused by the fact that i3 isn't running. The ideal scenario would be to add an if statement that checks if i3 is running, and if it is, then run the i3-msg command.
My question: What is the most convenient way to determine which window manager / Desktop Environment is currently running in my system?
When i3 is active, there should be a proces called "i3". You could check that with pgrep.
if pgrep -x "i3" > /dev/null
then
echo "i3 is running"
fi
-x is short for --exact – without it the if clause would still work, as long as no non-i3 process' name contains i3.
Omitting > /dev/null would print out the pid(s) found by pgrep.
Instead of pgrep you could also use pidof or ps -C. Instead of idiomatic if-then-fi you could also just use && like pidof i3 > /dev/null && echo "i3 is running" || echo "i3 is not running"

Screens Delete Themselves

So I'm attempting to make a start file which launches several screens each with their respective script. Looks a bit like:
cd /home/foo/
screen -dmS foo bash -c '/run.sh'
echo Started Foo
run.sh:
#!/bin/bash
while true
do
java -Xmx1024M -XX:MaxPermSize=256M -server -jar foo.jar -o true
sleep 5
done;
Now if I do screen -ls right after I run it, the screen shows up. However if I check a second later, the screens gone. Am I doing something wrong or is this the typical behavior?
I had to add sh to the start of the command because I didn't make it executable.

Resources