sh script gets stuck on read command in while loop - sh

I'm trying to write a script that I'll put in my pi's cron to check for network connectivity every 10 seconds, if it fails a ping to google it will write a text file as false, then next time it succeeds, it will restart a program, because the specific program has issues with reconnecting to the network automatically.
The script seemed to be working when I was executing it from the terminal out of the same directory, then I cd back to / and added a bunch of comments, and now it just exits the script without any output, and for the life of me I can't figure out where i messed it up - I'm still relatively new to scripting so I could be missing something absolutely obvious here, but I couldn't find anything useful on google.
file heirarchy:
/home/pi/WEB_UI/
inside the WEB_UI folder are both of the scripts i'm running here.
nonet.sh - the script in question
pianobar.sh - a simple script to pkill a program and reload it after 5 seconds.
var.txt - a text file that will only ever contain "true" or "false
I've tried removing all of the comments, changing the file locations to ./ and making the while; do commands a single line, but I can't figure out where the issue is. if I run sh -x for the script, it returns:
pi#raspberrypi:~/WEB_UI $ sh -x nonet.sh
+ ping -q -c 1 -W 1 google.com
+ read line
interestingly I get the same result from a test script I was using that was basically
"if var.txt says 'true', echo 'up', else echo 'down'"
I wonder if something is wrong with my sh interpreter?
#!/bin/sh
#ping google, if successful return true
if ping -q -c 1 -W 1 google.com >/dev/null; then
#read variable line, perform action do
while read line
do
#leading $ means return previous output. if line is false:
if [ "$line" = "false" ]
then
#return network up text, run pianobar script, set var.txt to true.
echo "the network is back up"
sh /home/pi/WEB_UI/pianobar.sh
echo true > /home/pi/WEB_UI/var.txt
else
#otherwise return network is up, set var.txt to true
echo "the network is up"
echo true > /home/pi/WEB_UI/var.txt
#fi ends an if statement, done ends a while loop.
#text after done tells the while loop where to get the line variable
fi
done < /home/pi/WEB_UI/var.txt
else
while read line
do
if [ "$line" = "false" ]
then
#if var.txt is already false, ping google again
if ping -q -c 1 -W 1 google.com >/dev/null; then
#if ping works, the network is back, restart pianobar, set var to true
echo "the network is back up"
sh /home/pi/WEB_UI/pianobar.sh
echo true > /home/pi/WEB_UI/var.txt
else
#if var.txt is false, network is still down. wait.
echo "the network is still down"
fi
else
echo "the network is down"
echo false > /home/pi/WEB_UI/var.txt
fi
done < /home/pi/WEB_UI/var.txt
fi
the script SHOULD just echo a simple line saying whether the network is up, down, back up, or still down, depending on how many flags it passes/fails. Any assistance would be greatly appreciated!

as Shellter said in comments above, the issue was that I needed to add \n to the end of the line in my var.txt
I think I saw another post recently where while read... was frustrated by a missing \n char, so maybe you want to do printf "false\n" > file instead. Good luck.

Related

How to install vncserver with a password?

I am trying to install tigervnc-server from a bash script with a password under Centos 6.
I want to do this because I want to automate VPS installations. Does anybody know how to do this? Tried adding two lines in the script with the password because it requires you to enter a password 2 times but it didnt worked, it said command not found and I didnt got past it. Thanks for the help!
#!/bin/bash
# Options:
PASSWORD="mysecret"
DISPLAY=":10"
VNCSERVER_OPTIONS="-geometry 1024x768 -alwaysshared"
PASSWD_PATH="$HOME/.vnc/passwd"
XSTARTUP_PATH="$HOME/.vnc/xstartup"
VNCSERVER="tightvncserver"
VNCPASSWD="tightvncpasswd"
# NOTE: you can change `tightvncpasswd` by `vncpasswd` if you don't use
# TightVNC but it won't work in some VNC implementations
NEW_SESSION="exec gnome-session"
vncserver_stop() {
# Kill server for this display if is running
$VNCSERVER -clean -kill $DISPLAY
}
vncserver_start() {
echo "$PASSWORD" | $VNCPASSWD -f > $PASSWD_PATH
chmod 600 $PASSWD_PATH
echo "$NEW_SESSION" > $XSTARTUP_PATH
$VNCSERVER $DISPLAY $VNCSERVER_OPTIONS
}
case "$1" in
start)
vncserver_start
;;
stop)
vncserver_stop
;;
restart)
tightvnc_stop
tightvnc_start
;;
*)
echo "Usage: $0 <start|stop|restart>"
exit 1
esac

Lock clearcase label type using korn shell scripting

I am trying to lock the label type using korn shell script but I am not able to lock.
As I am new to Korn scripts can some one help me.
Here is my current code:
cmUsers="user1,user2";
myuserName=$ENV{LOGNAME};
#checking whether current user is part of cmUsers list or not.
if [[ "$cmUsers" =~ m/$myUserName/i ]]
# if user belongs to cmUsers list, then trying to lock the lable type,
# if it fails exiting the process, else printing the success message
"ct lock -nuser \"$cmUsers\" lbtype:${label}#/vobs/admin_rec" ;then
die"Unable to lock label type: \"${label}\"\n";
else
print "Label ${label} has been successfully locked by $cmUsers"
fi
Beside the shebang, one simple tip is to avoid using an alias (ct) in a script: use the full command cleartool instead.
See also "Ksh Scripting" and "ksh class"
#!/bin/ksh
cmUsers="user1,user2";
myuserName=$ENV{LOGNAME};
#checking whether current user is part of cmUsers list or not.
if [[ "$cmUsers" =~ m/$myUserName/i ]]; then
# if user belongs to cmUsers list, then trying to lock the lable type,
# if it fails exiting the process, else printing the success message
cleartool lock -nuser \"$cmUsers\" lbtype:${label}#/vobs/admin_rec"
if [ $? -ne 0 ]; then
echo "CRITICAL: Unable to lock label type: \"${label}\""
exit 1
fi
echo "Label ${label} has been successfully locked by $cmUsers"
fi
However, an expression like $ENV{LOGNAME} points to the fact it might not be ksh or any other shell, but rather ratperl (if you are using ClearCase 7.x or more): see "About ratlperl and its impact on cqperl and ccperl"
In which case, remove the shebang, and try executing your script with:
ccperl yourScript.pl

Including some SFTP commands in a Makefile

I use a Makefile to create pdfs of papers I'm working on. I'd also like to use make to upload the latest version to my website, which requires sftp. I though I could do something like this (which words on the command line) but it seems that in make, the EOF is getting ignored i.e., this
website:
sftp -oPort=2222 me#mywebsite.com << EOF
cd papers
put research_paper.pdf
EOF
generates an error message
cd papers
/bin/sh: line 0: cd: papers: No such file or directory
which I think is saying "papers" doesn't exist on your local machine i.e., the 'cd' is being executed locally, not remotely.
Couple of ideas:
use ncftp which every Linux distro as well as brew should have: it remembers 'state' so the cd becomes unnecessary
use scp instead of sftp if possible
write a trivial shell script doing the EOF business and call that
For what it is worth, here is my script to push tarballs to the CRAN winbuilder -- and takes target directory and script as arguments to ncftpput.
#!/bin/bash
function errorexit () {
echo "Error: $1"
exit 1
}
if [ "$#" -lt 1 ]; then
errorexit "Need to specify argument file"
fi
if [ ! -f ${1} ]; then
errorexit "File ${1} not found, aborting."
fi
ncftpput win-builder.r-project.org /R-release ${1}
ncftpput win-builder.r-project.org /R-devel ${1}
I then just do wbput.sh foo_1.2-3.tar.gz and off it goes...
You cannot (normally) put a single command on multiple lines in a Make recipe, so here documents are a no-go. Try this instead:
website: research_paper.pdf
printf 'cd papers\nput $<\n' \
| sftp -oPort=2222 me#mywebsite.com
The target obviously depends on the PDF, so I made it an explicit dependency, as well.

Shell Script execution of Perl code causing weird results

I have a cron job that runs several shell scripts:
30 1 * * 1-5 /ufs/00/home/usr/bin/ConsentforFoo.sh "prd"
15 1 * * 1-5 /ufs/00/home/usr/bin/apptTvoxforFoo.sh
the first shell script looks like this:
#!/bin/bash
# ConsentforFoo.sh - set different environments, set path to perl scripts, calls script
TMP_HOME=/home/localweb/htdocs/cgi-bin/usr/CFoodir
if [ "$1" = "dev" ] || [ "$1" = "uat" ] || [ "$1" = "prd" ]
then
cd $TMP_HOME/$1
My-Consent-Cron.pl
else
echo "Val Not Set: $1"
fi
this script works flawlessly... However, the second shell script looks like this:
#!/bin/bash
# apptTvoxforFoo.sh - sends MHT population and patients with multiple appointments to west
TMP_HOME=/home/localweb/htdocs/cgi-bin/usr/CFoodir
cd $TMP_HOME
TvoxCron.pl #adding './' works here
but when it runs, I get an error saying: "sh: /ufs/00/home/usr/bin/apptTvoxforFoo.sh: cannot execute"
I add a "pwd" to the shell script and it's getting in the right directory and the file is there...
Weirdest thing is when I add "./" to it, it works... but in the first shell script I don't have to...
Any ideas why taking the if/then/else out would force me to SOURCE the perl script?
Thanks for any help you can provide.
Did you check the file permissions on the directories and all the files? Can you add a dot in front of the file to make sure you are not finding the file on the path?
./TvoxCron.pl

Script response if md5sum returns FAILED

Say I had a script that checked honeypot locations using md5sum.
#!/bin/bash
#cryptocheck.sh
#Designed to check md5 CRC's of honeypot files located throughout the filesystem.
#Must develop file with specific hashes and create crypto.chk using following command:
#/opt/bin/md5sum * > crypto.chk
#After creating file, copy honeypot folder out to specific folders
locations=("/share/ConfData" "/share/ConfData/Archive" "/share/ConfData/Application"
"/share/ConfData/Graphics")
for i in "${locations[#]}"
do
cd "$i/aaaCryptoAudit"
/opt/bin/md5sum -c /share/homes/admin/crypto.chk
done
And the output looked like this:
http://pastebin.com/b4AU4s6k
Where would you start to try and recognize the output and perhaps trigger some sort of response by the system if there is a 'FAILED'?
I've worked a bit with PERL trying to parse log files before but my attempts typically failed miserably for one reason or another.
This may not be the proper way to go about this, but I'd want to be putting this script into a cronjob that would run every minute. I had some guys telling me that an inotify job or script (I'm not familiar with this) would be better than doing it this way.
Any suggestions?
--- edit
I made another script to call the script above and send the output to a file. The new script then runs a grep -q on 'FAILED' and if it picks anything up, it sounds the alarm (tbd what the alarm will be).
#!/bin/bash
#cryptocheckinit.sh
#
#rm /share/homes/admin/cryptoalert.warn
/share/homes/admin/cryptocheck.sh > /share/homes/admin/cryptoalert.warn
grep -q "FAILED" /share/homes/admin/cryptoalert.warn && echo "LIGHT THE SIGNAL FIRES"
Use:
if ! /opt/bin/md5sum -c /share/homes/admin/crypto.chk
then
# Do something
fi
Or pipe the output of the loop:
for i in "${locations[#]}"
do
cd "$i/aaaCryptoAudit"
/opt/bin/md5sum -c /share/homes/admin/crypto.chk
done | grep -q FAILED && echo "LIGHT THE SIGNAL FIRES"