ShellScript for Killing and Starting Program every 5hrs - linux

I have a raspberry pi and I want to start a java application for 5 hours, kill it and start it again.
Because I need to login via SSH I thought it was clever to run the java application within screen (because I want to do other things while the program is running).
So without the script I started with:
screen -S java
java -jar program.jar
And then I send the Keys [CTRL] + [A] + [D] to detach.
Now I need to write this in shell.
I started with:
#!/bin/bash
#Check if app runs right now
OUTPUT="$(screen -ls)"
if [[ $OUTPUT == *"javaapp"* ]]
then
#Say that the javaapp is currently running
echo "javaapp is up!";
#Kill the javaapp!
screen -d javaapp #Does not work
fi
#Start it again
But it does not work :/
And I don't even know how to fix it since it's the first script I am trying to write. Is there anyone who can help me?
(Oh: And I would run the shellscript every 5hrs via. cronjob)
Thanks in advance!

Try this trick via cron:
#!/bin/bash
if [[ -f /opt/javaapp.pid ]]
kill -9 `cat /opt/javaapp.pid`
rm /opt/javaapp.pid
fi
nohup java -jar program.jar > /opt/javaapp.log 2>&1&
echo $! > /opt/javaapp.pid
Edit: I'm not sure it works with java apps though, or with apps that tend to fork and spawn other processes. Watch out for zombies if you try this.
Also, if anybody knows a better way, please share it. Now I'm curious.

Related

Parallel run and wait for pocesses from subshell

Hi all/ I'm trying to make something like parallel tool for shell simply because the functionality of parallel is not enough for my task. The reason is that I need to run different versions of compiler.
Imagine that I need to compile 12 programs with different compilers, but I can run only 4 of them simultaneously (otherwise PC runs out of memory and crashes :). I also want to be able to observe what's going on with each compile, therefore I execute every compile in new window.
Just to make it easier here I'll replace compiler that I run with small script that waits and returns it's process id sleep.sh:
#!/bin/bash
sleep 30
echo $$
So the main script should look like parallel_run.sh :
#!/bin/bash
for i in {0..11}; do
xfce4-terminal -H -e "./sleep.sh" &
pids[$i]=$!
pstree -p $pids
if (( $i % 4 == 0 ))
then
for pid in ${pids[*]}; do
wait $pid
done
fi
done
The problem is that with $! I get pid of xfce4-terminal and not the program it executes. So if I look at ptree of 1st iteration I can see output from main script:
xfce4-terminal(31666)----{xfce4-terminal}(31668)
|--{xfce4-terminal}(31669)
and sleep.sh says that it had pid = 30876 at that time. Thus wait doesn't work at all in this case.
Q: How to get right PID of compiler that runs in subshell?
Maybe there is the other way to solve task like this?
It seems like there is no way to trace PID from parent to child if you invoke process in new xfce4-terminal as terminal process dies right after it executed given command. So I came to the solution which is not perfect, but acceptable in my situation. I run and put compiler's processes in background and redirect output to .log file. Then I run tail on these logfiles and I kill all tails which belongs to current $USER when compilers from current batch are done, then I run the other batch.
#!/bin/bash
for i in {1..8}; do
./sleep.sh > ./process_$i.log &
prcid=$!
xfce4-terminal -e "tail -f ./process_$i.log" &
pids[$i]=$prcid
if (( $i % 4 == 0 ))
then
for pid in ${pids[*]}; do
wait $pid
done
killall -u $USER tail
fi
done
Hopefully there will be no other tails running at that time :)

Is it possible to auto reboot for 5 loops through mint?

I am currently using the following command to run reboot
sudo shutdown -r now
however, I would need to run it for 5 loops before and after executing some other programs. Was wondering if it is possible to do it in MINT environment?
First a disclaimer: I haven't tried this because I don't want to reboot my machine right now...
Anyway, the idea is to make a script that can track it's iteration progress to a file as #david-c-rankin suggested. This bash script could look like this (I did test this):
#!/bin/sh
ITERATIONS="5"
TRACKING_FILE="/path/to/bootloop.txt"
touch "$TRACKING_FILE"
N=$(cat "$TRACKING_FILE" | wc -c)
if [ "$N" -lt "$ITERATIONS" ]; then
printf "." >> "$TRACKING_FILE"
echo "rebooting (iteration $N)"
# TODO: this is where you put the reboot command
# and anything you want to run before rebooting each time
else
rm "$TRACKING_FILE"
# TODO: other commands to resume anything required
fi
Then add a call to this script somewhere where it will be run on boot. eg. cron (#reboot) or systemd. Don't forget to remove it from a startup/boot command when you're finished or next time you reboot, it will reboot N times.
Not sure exactly how you are planning on using it, but the general workflow would look like:
save script to /path/to/reboot_five_times.sh
add script to run on boot (cron, etc.)
do stuff (manually or in a script)
call the script
computer reboots 5 times
anything in the second TODO section of the script is then run
go back to step 3, or if finished remove from cron/systemd so it won't reboot when you don't want it to.
First create a text document wherever you want,I created one on Desktop,
Then use this file as a physical counter and write a daemon file to run things at startup
For example:
#!/bin/sh
var=$(cat a.txt)
echo "$var"
if [ "$var" != 5 ]
then
var=$((var+1))
echo "$var" > a.txt
echo "restart here"
sudo shutdown -r now
else
echo "stop restart"
echo 0 > a.txt
fi
Hope this helps
I found a way to create a file at startup for my reboot script. I incorporated it with the answers provided by swalladge and also shubh. Thank you so much!
#!/bin/bash
#testing making a startup application
echo "
[Desktop Entry]
Type=Application
Exec=notify-send success
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name[en_CA]=This is a Test
Name=This is a Test
Comment[en_CA]=
Comment=" > ~/.config/autostart/test.desktop
I create a /etc/rc.local file to execute user3089519's script, and this works for my case. (And for bootloop.txt, I put it here: /usr/local/share/bootloop.txt )
First: sudo nano /etc/rc.local
Then edit this:
#!/bin/bash
#TODO: things you want to execute when system boot.
/path/to/reboot_five_times.sh
exit 0
Then it works.
Don't forget edit /etc/rc.local and remove /path/to/reboot_five_times.sh when you done reboot cycling.

Linux, Bash execute commands in script after spawned process has ended

Writing a small bash script.
I have a command that spawns a process then returns, leaving the spawned process running. I need to wait for the spawned process to terminate, then run some commands. How can I do this?
The specific case is:
VBoxManage startvm "my_vm"
#when my_vm closes
do_things
However, I've encountered this issue before in other contexts, so if possible I'm looking for a general solution, rather than just one relating to virtualbox vm's.
I have an answer, and it's not pretty
tail --pid=$pid -f /dev/null
In the context of a VBox vm, the following heroic one-liner has proved successful.
VBoxManage startvm "my_vm"; tail --pid=$(awk '/Process ID:/ {print $4;}' /path_to/my_vm/Logs/VBox.log) -f /dev/null; echo hello
Running this, I was able to see that 'hello' was not output until after my_vm had shut down.
Good grief, there needs to be a better way of doing that than a side effect of an option of a command out of left-field. Any better answers? Please....
Unfortunately, I do not think you can generalize VirtualBox (or any process that spawns processes in the background) to one-size-fits-all solution.
Here is a VirtualBox specific answer.
As you noticed VBox runs the machine (and a bunch other things) in the background. But you can query VBoxManage for what is running:
vm_name="my_vm"
VBoxManage startvm $vm_name
while [[ `VBoxManage list runningvms | grep $vm_name` ]]; do
echo Sleeping ...
sleep 5
done
echo Done!
do_things
Hopefully you can tune this to your specific needs.

Keep a script running through ssh after logout

This is the first question that I post here. I tried to do a throughout search, but if I haven't (and the answer is obvious somewhere else), please just let me know.
I have a script that runs a program for me, here it is:
csv_file=../data/teste_nohup.csv
trace_file=../data/gnp.trace
declare -i n=100
declare -i p=1
declare -i counter=0
while [ $counter -lt 3 ];
do
n=100
while true
do
nice -19 sage gnptest.py ${n} ${p} | tee -a ${csv_file}
notify-send "finished test gnp ${n} ${p}"
done
done
So, what I'm trying to do is run the gnptest.py program a few times, and have the result be written to the csv_file.
The problem is, that depending on the input, the program may take a long time to complete. So I'd like to connect to the server over ssh, start the program, close the terminal, and check the output file from time to time.
I've tried nohup and disown. Nohup creates a huge nohup.out file, full with errors that I don't get while normally running the script (it complains about using the -lt operand, for example). But the biggest problem that I'm facing is that no command (nohup ou disown -h) is executing the program and sending the output to the file that I've specified in the csv_file variable, which is being done using the tee command. Also, none of them seem to continue running after I logout...
Any help will be much appreciated.
Thanks in advance!!
i hv just joined so cannt add comment
Please try by using redirection instead of tee in script
And to get rid of Nohup.out use following to run script
nohup script.sh > /dev/null 2>&1 &
If above produces error use
nohup script.sh > /dev/null 2>&1 </dev/null &
Hope this will help.

Autostart JavaFX Application on RaspberryPi

I programmed a JavaFX application which runs on a "Raspberry Pi" (a small ARM based Linux Computer). The OS on the "Pi" is "Raspbian" (a Debian Linux for Raspberry Pi). I installed JDK8 on Raspbian to run graphic JavaFX Application without X-Server. This all works fine :) I can start the Application by entering the following command:
/opt/jdk1.8.0/bin/java -cp /home/pi/sqljdbc4.jar:/home/pi/Leitwarte.jar leitwarte.Leitwarte
When the application starts it takes full control over mouse an keyboard, so there is no way back into console, but this doesent maters because it is just a monitoring system an i am able to shut the mashine down over ssh.
I now want to start the application directly after booting, so that there is no need for entering username ,passwort and starting the application.
The mashine does nothing else just running the app (of course there runs a ftp, ssh deamon for making updating the app posible)
Please tell me step by step, because i dont work with Linux for a long time.
Thank you very much.
CMD
cd /etc/init.d
sudo nano leitwarte
Enter the following
#! /bin/sh
# /etc/init.d/leitwarte
touch /var/lock/leitwarte
case "$1" in
start)
echo "Starting Leitwarte ... "
/opt/jdk1.8.0/bin/java -cp /home/pi/sqljdbc4.jar:/home/pi/Leitwarte.jar leitwarte.Leitwarte > /dev/null &
;;
stop)
echo "Killing Leitwarte ..."
killall java
;;
*)
echo "Usage: /etc/init.d/leitwarte {start|stop}"
exit 1
;;
esac
exit 0
then
chmod 755 leitwarte
update-rc.d leitwarte defaults
DONE
I solved this problem
When the application starts it takes full control over mouse an
keyboard, so there is no way back into console
by adding quotes ("") and by giving -Djavafx.platform=gtk for DEFAULT_JVM_OPTS.
For example in my case I replaced this code:
DEFAULT_JVM_OPTS=-XX:+UseG1GC -Dmode=prod_w_updates
to this:
DEFAULT_JVM_OPTS="-XX:+UseG1GC -Dmode=prod_w_updates -Djavafx.platform=gtk"
Hope, it will help

Resources