Meta refresh (refresh only browser) - bash

Can someone please tell me when I do "meta refresh" like below,will that also run bash program-run-tmp-directory3.sh &> stdout.out & again? OR, only the browser will be refreshed keeping the apache alive?
"pid" is the "process ID" of the program run in the background.
If this code below also reruns the program bash program-run-tmp-directory3.sh &> stdout.out &. Please let me know how can I avoid it?
#!/bin/sh
echo "Content-type: text/html"
echo ""
bash program-run-tmp-directory3.sh &> stdout.out &
pid=$!
if [[ `ps -p $pid | wc -l` -gt 1 ]]
then
output="Program is running. Running time depends on the number of alternatively spliced proteins the submitted gene has. Results will be displayed here."
echo "<html>"
echo "<head>"
echo "<meta http-equiv=\"refresh\" content=\"10\"/>"
echo "</head>"
echo "<body>"
echo "<table width=\"750\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
echo "<tr><td><img src=\"../../images/calc.gif\" align=\"absmiddle\"> <strong> $output </strong></td></tr>"
echo "</table>"
echo "</body>"
echo "</html>"
fi
Thanks.

At this point, it seems like your question is how to detect within a bash script that another script is running and avoid respawning it. A quick and dirty method that is often good enough is to grep the output of ps for the command-line of your script. This is slightly complicated by the fact that, depending on the options you use for ps, it may also display the grep process command-line, which obviously also includes the script's command-line as part of the grep pattern. One of many ways to fix this is here. All this explanation is longer than the actual script.
One more note. Just want to make sure you understand what the bash construct $! means:
($!) Expands to the process ID of the job most recently placed into
the background, whether executed as an asynchronous command or using
the bg builtin (see Job Control Builtins).
So, that's only going to refer to things that the current execution of your CGI script knows about. When your browser decides to refresh again, that sends another HTTP GET to your server, which once again spawns your CGI script, at which point $! only refers to the job most recently spawned by that instance of your script.
If I intuit what you're trying to do, you might want something like this (untested):
#!/bin/sh
echo "Content-type: text/html"
echo ""
# if other script not already running
if ! ps aux | grep "[b]ash.*program-run-tmp-directory3.sh"
then
bash program-run-tmp-directory3.sh &> stdout.out &
# I'm superstitious; let's give it a moment to start
sleep 1
fi
if ps aux | grep "[b]ash.*program-run-tmp-directory3.sh"
then
output="Program is running. Running time depends on the number of alternatively spliced proteins the submitted gene has. Results will be displayed here."
echo "<html>"
echo "<head>"
echo "<meta http-equiv=\"refresh\" content=\"10\"/>"
echo "</head>"
echo "<body>"
echo "<table width=\"750\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
echo "<tr><td><img src=\"../../images/calc.gif\" align=\"absmiddle\"> <strong> $output </strong></td></tr>"
echo "</table>"
echo "</body>"
echo "</html>"
else
: # ... some useful error output composed as HTML
fi

Related

Why does passing a variable from one bash script to another cause it to fail?

I have been trying to figure this one out for a while. I am trying to automate a few things. I only have rights to edit the scripts I write. I am currently using my script to call another script that I cannot edit, let's call it script.sh
I have tried:
if [[ -n $PASS ]]; then
su -c 'echo "$PASS" | ./script.sh' &
wait $!
else
./script.sh &
wait $!
fi
if [[ -n $PASS ]]; then
echo "$PASS" | ./script.sh &
wait $!
else
./script.sh &
wait $!
fi
if [[ -n $PASS ]]; then
./script.sh <<< $PASS &
wait $!
else
./script.sh &
wait $!
fi
This calls a script I cannot edit:
#!/bin/bash
echo "foo: "
read PASSWORD
echo
echo "foo"
...
if [ ! -f ./config.ini ]; then
./script2.sh ./config.ini
fi
My issue it that script.sh then calls another script, let's say script2.sh, that cats out a config.ini file to be used later in the process. Script2.sh fails to create config.ini correctly. Specifically the command user=$(/usr/bin/who am i | cut -d ' ' -f1) fails to set the variable.
So, 3 scripts deep one command fails. But it works if run manually or if I don't echo $PASS and enter it manually. Any ideas would be greatly appreciated.

Using while read, do Loop in bash script, to parse command line output

So I am trying to create a script that will wait for a certain string in the output from the command that's starting another script.
I am running into a problem where my script will not move past this line of code
$(source path/to/script/LOOPER >> /tmp/looplogger.txt)
I have tried almost every variation I can think of for this line
ie. (./LOOPER& >> /tmp/looplogger.txt)
bash /path/to/script/LOOPER 2>1& /tmp/looplogger.txt etc.
For Some Reason I cannot get it to run in a subshell and have the rest of the script go about its day.
I am trying to run a script from another script and access it's output then parse line by line until a certain string is found
Then once that string is found my script would kill said script (which I am aware if it is sourced then then the parent script would terminate as well).
The script that is starting looper then trying to kill it-
#!/bin/bash
# deleting contents of .txt
echo "" > /tmp/looplogger.txt
#Code cannot get past this command
$(source "/usr/bin/gcti/LOOPER" >> /tmp/ifstester.txt)
while [[ $(tail -1 /tmp/looplogger.txt) != "Kill me" ]]; do
sleep 1
echo ' in loop ' >> /tmp/looplogger.txt
done >> /tmp/looplogger.txt
echo 'Out of loop' >> looplogger.txt
#This kill command works as intended
kill -9 $(ps -ef | grep LOOPER | grep -v grep | awk '{print $2}')
echo "Looper was killed" > /tmp/looplogger.txt
I have tried using while IFS= read -r as well. for the above script. But I find it's syntax alittle confusing.
Looper Script -
./LOOPER
#!/bin/bash
# Script to test with scripts that kill & start processes
let i=0
# Infinite While Loop
while :
do
i=$((i+1))
until [ $i -gt 10 ]
do
echo "I am looping :)"
sleep 1
((i=i+1))
done
echo "Kill me"
sleep 1
done
Sorry for my very wordy question.

Is it logical to use the killall command to exit a script?

I am working around with a pin generator and I have come across a small issue.
I know of a few different methods to exiting a script but I have been playing around with calling the same script that is running as a child process, however when the child process is not called, the script exits perfectly. When called, the parent script does not exit properly after the child has completed and exited and the parent script loops back to the user input. I cannot think of anything other than possibly using the "wait" command though I don't know if this command would be proper with this code. Any thoughts on using the "killall" command to exit the script? I have tested it out, as you may see it in the code below, but I am left with the message, "Terminated" and if I can use killall how would I prevent that message from printing to standard out? Here is my code:
#!/bin/bash
clear
echo ""
echo "Now generating a random pin."
sleep 3
echo ""
echo "----------------------------------------------"
echo ""
# Generates a random 8-digit number
gen_num=$(tr -dc '0-9' </dev/urandom | head -c 8)
echo " Pin = $gen_num "
echo ""
echo "Pin has been generated!"
sleep 3
echo ""
clear
PS3="Would you like to generate another pin?: "
select CHOICE in "YES" "NO"
do
if [ "$CHOICE" == "YES" ]
then
bash "/home/yokai/Modules/Wps-options.sh"
elif [ "$CHOICE" == "NO" ]
then
clear
echo ""
echo "Okay bye!"
sleep 3
clear
killall "Wps-options.sh"
break
exit 0
fi
done
exit 0
You don't need to call the same script recursively (and then kill all its instances). The following script performs the task without forking:
#!/bin/bash
gen_pin () {
echo 'Now generating a random pin.'
# Generates a random 8-digit number
gen_num="$(tr -dc '0-9' </dev/urandom | head -c 8)"
echo "Pin = ${gen_num}"
PS3='Would you like to generate another pin?:'
select CHOICE in 'NO' 'YES'
do
case ${CHOICE} in
'NO')
echo 'OK'
exit 0;;
*)
break;;
esac
done
}
while true
do
gen_pin
done
You can find a lot of information about how to program in bash here.
First of all, when you execut
bash "/home/yokai/Modules/Wps-options.sh"
The script forks and crates a child process, then, it waits for the child termination, and it does not continue with execution, unless, your script Wps-options.sh executes something else in background (forking again) without reaping its child. But i can not tell you more because i dont know what is in your script Wps-options.sh
To prevent messages to be printed to stdout when you execute killall:
killall "Wps-options.sh" 1> /dev/null 2> /dev/null
1> stands for stdout redirection to file /dev/null and 2> stands for stderr redirection to file /dev/null

How to write info to the file from bash script and see the result immediately?

I need help. I can't understand how I can write information to the file from bash script and see the result immediately.
For example:
#!/usr/bin/env bash
PID=$$
echo "PID is $PID"
echo $PID > my_script.pid
echo "Sleeping..."
sleep 5
echo "Finished"
PID number appears in console immediately, but in the file I see it after script finished.
I have Mac OS X Yosemite 10.10.3.
I tried a lot of stuff with flush buffering. NO result:(
Please, help!
Update.
My goal is to define if another instance of that script is still running. I decided to use pid file and condition:
PID=`cat $PID_FILE`
if ps -p $PID > /dev/null; then
echo "script already running"
exit 1
fi
Maybe there is a more efficient way?
You must be trying to read it too soon. To confirm that it's being written right away change the script to:
#!/usr/bin/env bash
PID=$$
echo "PID is $PID"
echo "$PID written to file." >> my_script.pid
echo "Sleeping..."
sleep 5
echo "Finished"
Then run:
touch my_script.pid
tail -F my_script.pid &
./my_script.sh
The tail -F command will run on the background and will output whatever is written to my_script.pid shortly after it's written. The delay you see is on tail, once echo returns it is written.
Sorry for misunderstanding. Actually it works fine. The problem in GUI tool (PyCharm) where I checked out file modification. It has interesting delay.
So when I check out previous PID from the same script it works fine:)
Thanks a lot fernan for help;)

how to create and send output directly to printer using do shell script

I am trying to get a shell script that works in the sh shell to work as an applescript do shell script command. The script simply takes a series of elp2 commands and pipes them to lpr for printing. This works when typed directly into the shell, but when run in applescript it does not print. The printer is receiving data but it is not formated correctly so nothing prints. I believe the issue is with the way the quotes are escaped. Here is the code:
do shell script "{ echo N
echo OD10
echo q812
echo Q1218,24
echo D15
echo ZT
echo A70,40,0,5,3,3,N,\\'F\\'
echo A610,70,0,3,1,1,N,\\'U.S.\\'
echo A590,95,0,3,1,1,N,\\'POSTAGE\\'
echo A580,120,0,3,1,1,N,\\'REQUIRED\\'
echo A43,240,0,4,2,1,N,\\'USPS FIRST-CLASS MAIL\\'
echo A43,300,0,3,1,1,N,\\'Name\\'
echo A43,325,0,3,1,1,N,\\'street\\'
echo A43,350,0,3,1,1,N,\\'city, VA 12345\\'
echo A43,400,0,3,1,1,N,\\'ADDRESS SERVICE REQUESTED\\'
echo A140,490,0,4,1,1,N,\\'ship to\\'
echo A140,520,0,4,1,1,N,\\'company\\'
echo A140,550,0,4,1,1,N,\\'address\\'
echo A140,580,0,4,1,1,N,\\'city, state, 12345\\'
echo A140,610,0,4,1,1,N,\\'country\\'
echo A140,640,0,4,1,1,N,\\'\\'
echo LO10,10,760,4
echo LO10,210,760,2
echo LO10,275,760,2
echo LO10,750,760,10
echo LO10,1050,760,10
echo LO10,1185,760,4
echo LO10,10,4,1175
echo LO770,10,4,1175
echo LO210,10,2,200
echo LO540,45,200,2
echo LO540,45,2,125
echo LO540,170,200,2
echo LO740,45,2,125
echo P1
echo N;} | lpr -P Label -o raw"
One way you can check how to write something in applescript is to write the normal unescaped text into a text file. Then you read the file into applescript. What you see in the result field is how you should write it. You can then copy/paste the result into your applescript.
For example, if I make a text file on my desktop called myText.txt with this inside...
echo A70,40,0,5,3,3,N,\'F\'
echo A610,70,0,3,1,1,N,\'U.S.\'
Then I use this applescript...
set f to (path to desktop as text) & "myText.txt"
read file f
My result is...
"echo A70,40,0,5,3,3,N,\\'F\\'
echo A610,70,0,3,1,1,N,\\'U.S.\\'"
So give that technique a try with your entire code. Good luck.

Resources