Detecting the PC is running on UPS Power and shutdown Computer - bash

I'm downloading huge sums of data at night and my PC in running through a UPS. Is there any way I can detect a power failure and command my PC to shut down automatically? Because I work at night, and there's no one to switch off the PC, it would be really helpful if anyone could help. Is it possible?
Thanks.

IMPORTANT: The scripts presented below will cause the system to shutdown whenever the network is down, so use them at your own risk!
A not so elegant way of doing what you want, if you have a network host (e.g. your router) that responds to ICMP echo requests and is not powered by the UPS (or at least the networking equipment is not powered by the UPS), would be to ping that host every few seconds and if it's down then shutdown the PC:
#!/bin/bash
while :
do
ping -c 1 -w 5 192.168.0.1 &> /dev/null
if [ $? -gt 0 ]; then
shutdown -hP now
break
fi
sleep 10s
done
You will have to change 192.168.0.1 to the IP address of the network host you want to ping.
You will also have to make the script executable with chmod +x <script_name> and place a call to it in /etc/rc.local (do not forget to append a & to make it run in the background) which will run the script as root on boot.
For completeness' sake, if the PC was running Windows XP one could use the following batch file:
:loop
ping -n 1 -w 5000 192.168.0.1
if not %ERRORLEVEL% == 0 (
shutdown -s
goto end
)
sleep 10
goto loop
:end
Note that the Windows batch file requires the sleep command which can be installed as part of the Windows Server 2003 Resource Kit Tools package (available as a free download from Microsoft's site)

If it's an APC and it has a data port you can use PowerChute. It's a java-based GUI (which could be a problem if this is your server) that does exactly what you are requesting.

Related

AppleScript: how restart automatically the internet connection when it's stuck

When I upload a big amount of files through FTP for some reason my WiFi connection stops working. The connection doesn't show any problem and for solving this it's enough disable and re-enable the wifi. How to restart automatically it using AppleScript in the Script Editor?
My solution's this script that every second checks the connection to google and if there is a timeout close and reopen the en0 connection.
log "Internet checker: let's go"
repeat while true
try
do shell script "nc -w 4 -z 8.8.8.8 53"
# do shell script "nc -w 4 -z apple.com 80"
log "External TCP call test works"
on error
log "Restarting internet..."
do shell script "networksetup -setairportpower Wi-Fi off"
delay 2
do shell script "networksetup -setairportpower Wi-Fi on"
log "Done."
delay 8
end try
delay 2 # wait a moment before the next internet checking
end repeat
Update 24 Aug 022: This should be my 'definitive edition' of the script: privileges are no more requested. It used to be pretty slow to discover the lack of internet connection despite the -w timeout, so I try to ask directly to a "standard de facto" IP (a DNS server).
For more information about nc command you can consult this link: https://www.computerhope.com/unix/nc.htm

Automatic shutdown of Windows 10 computer from bash script

I have a problem with my power failure monitoring scheme / automatic shutdown of Windows 10 computer.
On my network I have a Linux box that has a UPS unit connected via USB and maintained with software which makes the computer shut down when power failure occurs.
On another computer, also powered from the same UPS unit running headless Windows 10 server, I have setup a simple bash script (cygwin) running from Task Scheduler.
It is supposed to shutdown this computer once the aforementioned Linux box stops responding to ping on the network (because it shuts down when power failure is detected).
The UPS unit is setup to shut the power down after 10 minutes from power failure, giving plenty of time for the Windows machine to detect lack of response from Linux box and executing shutdown.
Here is the monitoring script code:
#!/bin/bash
upshost="<linux-box-ip>"
echo "UPS Host: $upshost"
while true
do
date
ping -c3 $upshost >/dev/null
if [[ $? -ne 0 ]]
then
echo "WARNING: Ping failed, trying again in 30 seconds ..."
sleep 30
ping -c3 $upshost >/dev/null
[[ $? -eq 0 ]] || break
fi
echo "Host $upshost responded to ping."
sleep 30
done
date
echo "ERROR: Host $upshost didn't respond to ping."
echo "System will shutdown in 1 minute."
shutdown -h +1 "System will shutdown in 1 minute."
NOTE: is the actual IP address of my Linux box which is always the same (reserved in the router setup).
The task scheduler properties:
Runs from SYSTEM account, whether user is logged on or not, with highest privileges.
Triggers: at system startup
Actions: Start a program
program/script -> c:\cygwin64\bin\bash
arguments -> -l -c "/cygdrive/c/bin/pwrwdog.sh > /cygdrive/c/tmp/pwrwdog.trc"
runs in -> c:\cygwin64\bin
Start if any network connection is available.
I see in traces and in task scheduler history that script properly monitors the network response from Linux box, breaks out of the monitoring loop when host stops responding and invokes shutdown command. The problem is - the shutdown doesn't actually happen:
Host <linux-box-ip> responded to ping.
Sun, Jan 3, 2021 7:23:48 AM
Host <linux-box-ip> responded to ping.
Sun, Jan 3, 2021 7:24:20 AM
WARNING: Ping failed, trying again in 30 seconds ...
Sun, Jan 3, 2021 7:25:16 AM
ERROR: Host <linux-box-ip> didn't respond to ping.
System will shutdown in 1 minute.
System will shutdown in 1 minute.
What do I miss?

Make bash wait until remote server kickstart is done (it will create a file when it's done)

I am creating a script to kickstart several servers. I am nearly finished, however I want the bash script to wait until the server kickstart is done.
When the kickstart is done and the server is rebooted a file will be created on the remote kickstarted server which is located under "/root/" and is called "kickstart-DONE"
Is it possible to make the bash script wait until it sees this file and then post something like "Done!"...?
I tried searching the forums and internet, but probably I am searching incorrectly, as I was unable to find something relevant to this issue. Heck, I don't even know if this is possible at all.
So in short; I run my script which kickstarts a server. After the kickstart is done it will create a file on the remote (- kickstarted) server called: kickstart-DONE. This would be an indication for the script that the kickstart is fully done and the server can be used. How do I make the script aware of this?
I hope someone understands what I mean and trying to achieve....
Thanks in advance.
//EDIT
SOLVED! Thanks to Cole Tierney!
Cole Tierney gave some good answers, however though it works it does not wait until the server is kickstarted. I ran the script to kickstart a server and in the end it was running the provided command:
ssh root#$HWNODEIP "while ! test -e /root/kickstart-DONE; do sleep 3; done; echo KICKSTART IS DONE...\!"
However since the kickstart can take some time (depending on server speed and such; ranging from 15 minutes to 1 hour). The command timed out:
ssh: connect to host 100.125.150.175 port 22: Connection timed out
Is there a way that the script does not time out at all and keeps it alive until the server gets back or until it takes more than 1 hour or so?
Maybe there is also a way to make it show that the script is still active? Like "Waiting... 5 minutes passed." "Waiting... 10 minutes passed." etc.
So it gives the current user some information that it not died?
You could call sleep until the file exists:
while ! test -e /root/kickstart-DONE; do sleep 3; done; echo kickstart done
Or sleep until the server is accepting ssh connections. Run the following netcat command locally to check when port 22 is open on the server (remove echo closed; if you don't want the extra feedback):
while ! nc -zw2 $HWNODEIP 22; do echo closed; sleep 3; done
On a side note, it's useful to setup a host entry in ~/.ssh/config. You can add all sorts of ssh options here without making your ssh command unwieldy. Options that are common to all host entries can be added outside of the host entries. See man ssh_config for other options. Here's an example (server1 can be anything, replace <server ip> with the server's ip address):
Host server1
Hostname <server ip>
User root
Then to use it:
ssh server1 'some command'
Note that many systems will not allow ssh connections from root for security reasons. You may want to consider adding another user for kickstart stuff. Add this user to sudoers if root access is needed.

tcpprobe does't exist in /proc/net/ when I used SSH

I am new in world of network. I made a simple SDN that contains 3 hosts, one switch and a controller. I would like to monitor the traffic using tcpprobe. I opened a terminal using xterm h1 and ran the shell there. I also made iperf server in h2. But the tcpprobe was not existed in /proc/net/ directory when I use a SSH terminal!
enter image description here
However I installed it on my VM and it is exist in /proc/net/ of my VM.
enter image description here
sudo apt-get install transcode
Here is my shell code:
#!/bin/bash
#used variables
eth=h1-eth0
port_to_probe=5001
#we will probe the iperf port
server_addr=10.0.0.2
#LOAD TCP CONGESTION CONTROL MODULES
modprobe tcp_probe port=$port_to_probe full=1 bufsize=50
for time_test in 10 20 30 60 10 20
do
echo "Traffic transmission time set to " $time_test "s randomly.\n"
#start logging data
sudo cat /proc/net/tcpprobe > tcprobe.dat &
#get the cat process ID to later kill it
pid=$!
#kill the logger
kill $pid
done
Can anybody help me?
The problem was that, each SSH use a port to connect to VM and this cause a change on the address of /proc/net/. To solve this problem it is enough to change the mentioned address to /proc/6337/net/. By reading this address in fact you read the real VM directory. So the final code will change to:
cat /proc/6337/net/tcpprobe

Bash script to monitor ISDN connection

On a Ubuntu 10.04 Server I would like to do the following with a bash script:
Create a service that monitors the ISDN connection and if downtime exceeds 60 seconds forces reconnect.
My current solution looks something like this:
#!/usr/bin/bash
LOGFILE=/home/msw/router/ping-stats.txt
TIME="`date +%C%y%m%d%H%M`"
/sbin/ping -c 1 google.com > /dev/null 2>&1
if [ "$?" == "0" ]
then
STATUS=1
else
STATUS=0
fi
echo "$TIME $STATUS" >> $LOGFILE
Since bandwidth is precious on an ISDN connection, I would like to avoid the ping and replace it with a command that simply checks for the status of the network device. Is it possible to infer from that if the connection is "up"?
I would also like to implement the solution as a service that checks connectivity continually instead of checking periodically with a cronjob.
I would really appreciate it if somebody could push me in the right direction.
Thank you
For quick-and-dirty there's nm-tool. dbus-send can be a bit more precise, but needs knowledge of how D-Bus works with NetworkManager. If you want something persistent then you'll need to learn how to interact with D-Bus, but that may require using something a bit lower-level such as Python.
Is your ISDN provided by an internal adapter or via an Ethernet connection? If you have an external "modem" you'd need to query that using SNMP or its proprietary facility.
You can do your test this way, by the way:
if /sbin/ping -c 1 google.com > /dev/null 2>&1
then
...
Also, a single ping is a very small number of bytes. If you're only doing it a few times a minute you may never notice it.

Resources