To learn about BASH scripting, I set myself the objective to write a Cron script which shuts down a PC with Mint 20 when activity on the Ethernet interface dropped below a threshold over an 1 hour.
I mainly (but not exclusively) use the PC as File/DLNA Server. The script works, but now I find that it also shuts down the PC the rare times I'm using the the front end. So I want my script to verify if the screen has been blanked (As per Power Management settings)
To test the principle I included this in my script:
screenon=$(/usr/bin/xset -q | grep 'Monitor is' | cut -d "s" -f 2)}
which when run in a terminal window gives (debug: set -x)
screenon= On
but when run from cron gives. (logger)
/usr/bin/xset: unable to open display ""
I have learned about similar problems, but cannot figure out how to solve this.
My script includes:PATH=$PATH:/usr/local/bin
and my PATH is: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
Thanks in advance for any help.
Related
Due to some issues I wont elaborate here to not waste time, I made a bash script which will ping google every 10 minutes and if there is a response it will keep the loop running and if not then the PC will restart. After a lot of hurdle I have been able to make the script and also make it start on bootup. However the issue is that i want to see the results on the terminal, meaning I want to keep monitoring it but the terminal does not open on bootup. But it does open if I run it as ./net.sh.
The script is running on startup, that much I know because I use another script to open an application and it works flawlessly.
My system information
NAME="Linux Mint"
VERSION="18.3 (Sylvia)"
ID=linuxmint
ID_LIKE=ubuntu
PRETTY_NAME="Linux Mint 18.3"
VERSION_ID="18.3"
HOME_URL="http://www.linuxmint.com/"
SUPPORT_URL="http://forums.linuxmint.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/linuxmint/"
VERSION_CODENAME=sylvia
UBUNTU_CODENAME=xenial
The contents of my net.sh bash script are
#! /bin/bash
xfce4-terminal &
sleep 30
while true
do
ping -c1 google.com
if [ $? == 0 ]; then
echo "Ping Sucessful. The Device will Continue Operating"
sleep 600
else
systemctl reboot
fi
done
I have put the scripts in /usr/bin and inserted the scripts for startup at boot in /etc/rc.local
So I did some further research and with help from reddit I realized that the reason I couldnt get it to show on terminal was because the script was starting on bootup but I needed it to start after user login. So I added the script on startup application (which can be found searching on start menu if thats whats it called). But it was still giving issues so I divided the script in two parts.
I put the net.sh script on startup and directed that script to open my main script which i named net_loop.sh
This is how the net.sh script looks
#! /bin/bash
sleep 20
xfce4-terminal -e usr/bin/net_loop.sh
And the net_loop.sh
#! /bin/bash
while true
do
ping -c1 google.com
if [ $? == 0 ]; then
echo "Ping Sucessful. The Device will Continue Operating"
sleep 600
else
systemctl reboot
fi
done
The results are the results of the net_loop.sh script are open in another terminal.
Note: I used help from this thread
If minute interval is usable why not use "cron" to start your?
$> crontab –e
or
$> sudo crontab –e
So I've recently started using Ubuntu on WSL2, and I'm trying to use X2Go as my X window system to run GUI apps. I start up the Ubuntu WSL, and run the SSH daemon. Then, I use the x2go client on Windows to connect to the X2Go server running on the Ubuntu WSL, and it all works fine.
But I want to normally use the Windows Terminal for running BASH, and run the GUI applications in the X2Go client. For this, the $DISPLAY environment variable needs to be set.
In this case, the value for the environment variable would be DISPLAY=:60.0 (where 60 is the display number in the screenshot above and 0 indicates monitor 0). But, every time I restart the client session, I get a different display number (previous display number + 1), and the value of the environment variable needs to be changed again.
Is there any way I can make the display number consistent and set the DISPLAY environment variable in .bashrc so that I do not need to export it every time? I'm new to this, so let me know if something doesn't make sense or if there's an entirely different approach that's better for this.
Not exactly what you are after, but you can find the display number by looking at the full command line for the x2goagent process -- the display will be at the end:
$ pgrep -a x2goagent
So if you add the following to your .bashrc
x2g() {
export DISPLAY=`pgrep -a x2goagent | rev | cut -d " " -f 1 | rev`
}
you can use the x2g function at the bash prompt to set your DISPLAY variable to wherever X2Go has decided to put the screen this time:
$ x2g
$ echo $DISPLAY
:55
It's not ideal because you need to enter this command for every shell, and do so after you have started the X2Go session. But it's a bit easier than finding the display manually every time.
Note that if you were to use a terminal executing within the WSL environment where the X2Go agent is running, DISPLAY is set automatically to the correct value (as long as you don't redefine it somewhere in your .bashrc or equivalent). I understand from your question that you are working from the Windows terminal running bash, however, you could potentially use (say) an xterm running in WSL for launching X11 apps, then continue to use the Windows terminal for everything else.
On Mac OS is it possible to create an Automator/Bash/Java/ApplieScript that runs an bash-command to do something (for example chance the screen resolution) after that runs an application (for example a game that needs a specific screen resolution) then waits until the application has been terminated and after that does one final thing (for example change the screen resolution again)?
I tried to work with all Automator, Bash, Java and ApplieScript. I even tried to combine multiple of them to one chain of things that runs other things just to run something else until it terminates and then run something else, but non of that semms to work properly.
I got the terminal commands that changes screen resolution and I also got the terminal command that runs the Game, but I can't bring it together in an logical correct chain of things to happen...
The Commands are:
do shell script "/Volumes/Sierra/Users/xyz/Documents/cscreen -x 1600 -y 900 -r 60"
do shell script "open steam://run/8930"
do shell script "/Volumes/Sierra/Users/xyz/Documents/cscreen -x 1280 -y 720 -r 60"
What you want is the -W argument for open:
-W Causes open to wait until the applications it opens (or that were already open) have exited. Use with the -n
flag to allow open to function as an appropriate app for the $EDITOR environment variable.
So in your example I would make a script like this:
#!/bin/bash
/Volumes/Sierra/Users/xyz/Documents/cscreen -x 1600 -y 900 -r 60
open -W steam://run/8930
/Volumes/Sierra/Users/xyz/Documents/cscreen -x 1280 -y 720 -r 60
Now open should not return control to the shell until steam exits.
First some background: I'm using the LaunchD feature in Mac OSX to periodically launch an application I'll call "AppX". Optimally I like to run this application nearly 24/7. But due to issues with memory leakage (that is my best guess), AppX closes periodically. To solve this, I've created and loaded a simple plist file to launch the application every 6 hours. This itself works perfectly and minimizes application downtime. However, AppX itself can be a drain on my battery, and I'd prefer it only launch when I'm at home, connected to my wifi network.
Please be aware that while I have some experience with C++ and Java, I know very little in the way of Unix.
My question: I'd like to use an if statement to check whether the network I'm connected to is my home wifi network. Being the case that it is, the system will execute the command:
open -a AppX
So... How would I implement an if statement to accomplish this? Any help is appreciated.
There's an older SO question that gives part of the answer:
Get wireless SSID through shell script on Mac OS X
As for the if statement, the following should work:
homenet = "MyHomeNetwork"
netname = /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | awk '/ SSID/ {print substr($0, index($0, $2))}'
if [ "$netname" -eq "$homenet" ]
then
# Do fancy service startup here
else
# This is not my home network
fi
I have a program that runs as a daemon, using the C command fork(). It creates a new instance that runs in the background. The main instance exists after that.
What would be the best option to check if the service is running? I'm considering:
Create a file with the process id of the program and check if it's running with a script.
Use ps | grep to find the program in the running proccess list.
Thanks.
I think it will be better to manage your process with supervisord, or other process control system.
Create a cron job that runs every few minutes (or whatever you're comfortable with) and does something like this:
/path/to/is_script_stopped.sh && /path/to/script.sh
Write is_script_stopped.sh using any of the methods that you suggest. If your script is stopped cron will evaluate your script, if not, it won't.
To the question, you gave in the headline:
This simple endless loop will restart yourProgram as soon as it fails:
#!/bin/bash
for ((;;))
do
yourProgram
done
If your program depends on a resource, which might fail, it would be wise to insert a short pause, to avoid, that it will catch all system resources when failing million times per second:
#!/bin/bash
for ((;;))
do
yourProgram
sleep 1
done
To the question from the body of your post:
What would be the best option to check if the service is running?
If your ps has a -C option (like the Linux ps) you would prefer that over a ps ax | grep combination.
ps -C yourProgram