Unsolved Syntax Error in Bash Function - linux

I'm writing a script for a Raspberry Pi that I had working a few days ago, but now seems to have died once I added some additional code. I've attempted to resuscitate, but I'm coming up short. I am getting "Syntax error near unexpected token `done". I've researched it, but I'm not getting anywhere. dos2unix doesn't help (especially since I've coded the entirety of this on Debian 8.) and cat -v doesn't turn up anything. Offending module is as follows:
24Monitor() {
clear
echo "Beginning speed tests and traceroutes now. You can just... go do whatever it is you do."
while [ $SECONDS -lt $end ]; do
TestNum=$(($TestNum+1))
echo "Speedtest Result #" $TestNum >> ~/speedtest.log
curl -s https://raw.githubusercontent.com/sive/speedtest-cli/master/speedtest.py | python -
cat ~/tmp.log | sed -e "s/^/$(date -R) /" >> ~/speedtest.log
echo "" >> ~/speedtest.log
traceroute mayernetworks.com > ~/traceroutes.log
done
}
I would appreciate any and all insight, as I'm still growing in my scripting knowledge...
EDIT: Variable initilization by request:
end=$((SECONDS+86400))

Related

clear my script logs every 10 second

I have script with name : run.sh
This is my script code :
#!/usr/bin/env bash
install() {
sudo apt-get update
sudo apt-get upgrade
}
if [ "$1" = "install" ]; then
install
else
if [ ! -f ./tg/tgcli ]; then
echo "tg not found"
echo "Run $0 install"
exit 1
fi
#sudo service redis-server restart
#./tg/tgcli -s ./bot/bot.lua -l 1 -E $#
./tg/tgcli -s ./bot/bot.lua $#
fi
and when run this script give me output like this every second :
[09:54] 2014 Hello
[09:55] 2014 Hi
[09:57] 2014 How Are you ?
and many like this (thousands in hour !)
and my server get slow in 5 hour.
i check print commands in bot.lua but there are no way to remove print it.
can you add some codes to clear my script logs every 10 second ?
Thanks a lot.
My Script Output Doesn't Save Anywhere and Just Show me in terminal
I want a code such as clear command on linux terminal , clear my script logs every 10 minute or 5 minute.
After 5 day of script running i can (sometimes can't) login my server and my server get very slow and i must wait 3 or 5 minute to login my server and this amazing after login my server my server again get fast !
and i forgot say i use byobu screen for run my scripts and I think screen get my server slow down.
I don't think that something as simple as this would cause your server to slow down, but you can add a check to your script to calculate the size or line count of your log file every time it runs.
This function assumes you are redirecting your output to a log file. Set the variables to whatever makes the most sense.
log_check() {
line_count=$(wc -l $log_file | awk '{print $1}')
size_check=$(du -ax $log_file | awk '{print $1}')
max_file_size="1500"
max_file_length="1000"
if [[ $line_count >= $max_file_length || $size_check >= $max_file_size ]]; then
echo "" > $log_file
fi
}
I would also recommend using [[ ]] over [ ] since this is a bash script, as long as you don't plan in it being posix compliant and only plan on using it with bash [[]] is always better than [].
EDIT:
Since you are logging output to the terminal and not a file you can literally use the clear command in your script.
Try this out and see how the functionality works
for i in {1..20}; do
echo $i
if (( i == 10 )); then
clear
fi
done
I'm assuming your code has a loop somewhere, if not it will be a bit more complex to clear the terminal session. I'm not really sure what part of your code is actually printing anything to stdout, I'm guessing it's this piece here
./tg/tgcli -s ./bot/bot.lua $#
You could try something like this, which will background your initial process and then run clear every 60 seconds to clear the terminal window. Is there any reason you're not writing the output to a log file? That alone could solve some of your issues as well.
#!/bin/bash
./tg/tgcli -s ./bot/bot.lua $# &
pid="$!"
check_pid() {
ps -ef |grep "$pid"|grep -v 'grep' &>/dev/null
}
cnt=1
until ! check_pid; do
if (( cnt == 6 )); then
clear
cnt=1
fi
sleep 10
((cnt++))
done

Bash - while loop syntax error

I'm new to bash scripting, and atm I'm trying to learn it.
When I run this bash code:
#!/bin/bash
while true
do
./pokecli.py
echo ">pokecli exited... restarting...";
sleep 5;
done;
I receive this error:
opt/PokemonGo-Bot# ./start.sh ./start.sh: line 6: syntax error near unexpected token `done'
./start.sh: line 6: `done;'
Any help is appreciated
You have semicolons where it's not needed. Also, you should start indenting nested commands and get your do on the same line as the while for readability. In addition, "while true" can be dangerous, and a "while sleep" is better.
#!/bin/bash
while sleep 5; do
./pokecli.py
echo ">pokecli exited... restarting..."
done
However, that being said-- none of that will cause an error. Most likely you have either typo'd your do, commented it out, or have (most likely) a Windows (or other special) character prior to the "do", like a ^M or such. The dos2unix command might help, or run this.
tr -cd '[:graph:]\n\t ' <start.sh >file.tmp && mv file.tmp start.sh
You'll have to chmod +x the script again.
The correct syntax is
7.3 While sample
#!/bin/bash
COUNTER=0
while [ $COUNTER -lt 10 ]; do
echo The counter is $COUNTER
let COUNTER=COUNTER+1
done
So you should change to
#!/bin/bash
while true; do
./pokecli.py
echo ">pokecli exited... restarting...";
sleep 5;
done

BASH save stdout to new file upon execution

please bear with me if my terminology or syntax is less than stellar (still learning). I currently have a simple bash script that checks the arguments of the command and outputs files names with matching text. This part of my script works correctly via a grep command and piped to xargs for proper formatting.
When running the script, I run through a simple loop to check if the value is null and then move to running my variable/search if not.
My question is: Is it possible to have this script output via stdout AND also save a new file each time it is run with the user input and date/time? (but not overwrite) EX: report-bob-0729161500.rpt
I saw same other suggestions to use tee with the command, but I was trying to get it to work within the script. Similarly, another suggestion stated to utilize exec > >(tee -i logfile.txt), but I am unsure how to properly format this to include the date/time and $1 input into new files each time the script is executed.
Any help or suggested resources?
Thank you.
SEARCH=`[search_variable]`
if [ -z "$SEARCH" ]
then
echo "$1 not found."
else
echo -e "REPORT LISTING\n\n"
echo "$SEARCH"
fi
EDIT: I did try simply piping the echo statements to the tee command, which does work. However, I am still curious if anyone has other suggestions to accomplish this same task via alternative methods. Thank you.
With echo statements piped to tee:
SEARCH=`[search_variable]`
DATE=`date +"%m%d%y%k%M"`
if [ -z "$SEARCH" ]
then
echo "$1 not found."
else
echo -e "REPORT LISTING\n\n" | tee tps-list-$1-$DATE.rpt
echo "$SEARCH" | tee tps-list-$1-$DATE.rpt
fi
If you want to do it within the script, why then not just write to
both standard output and the file (using append where appropriate?).
Maybe a bit more writing, but it gives complete control.
Leon

Grep not working in script but on console

I have a problem with a script. I have a voltage meter connected to a serial USB device(ttyUSB1).
The smart meter needs an initial sequence and shortly followed by a second command to give all of it's information. That works fine. 1.8.0*00(000898.46) for example comes in this is the line I am interested in. The number in brackets is the kWh number i want. If i open a second terminal and do a cat /dev/ttyUSB1 it works fine and i can see the information coming in. After 4 to 5 seconds the line I want comes in. But the script is not working. If i start a script in one terminal it keeps waiting. Grep is not finishing. If I start it in a second terminal then the first terminal gets finished. Or just the grep 1.8.0 /dev/ttyUSB1 -m1 in another terminal works but not in the script.
I tried different methos with read and so none worked. To be honest i don't understand much of scripting and always succeed somehow but here nothings helped :(
Please help. Thank you!
Arne
here the script:
#! /bin/bash
echo start
echo $'\x2f\x3f\x21\x0d' > /dev/ttyUSB1
sleep 1
echo ask
echo $'\x06\x30\x30\x30\x0d' > /dev/ttyUSB1
echo wait
grep 1.8.0 /dev/ttyUSB1 -m1
echo end
You can try creating a file with voltimeter's output and grep from that file:
#! /bin/bash
dev=/dev/ttyUSB1
file=/tmp/testfile
(tail -f $dev | tee $file) & # let's continuously copy in background
echo start
echo $'\x2f\x3f\x21\x0d' > $dev
sleep 1
echo ask
echo $'\x06\x30\x30\x30\x0d' > $dev
echo wait
grep 1.8.0 $file # lets get the info from the file instead
echo end
sleep 1
exit

Shell script for parsing log file

I'm writing a shell script to parse through log file and pull out all instances where sudo succeeded and/or failed. I'm realizing now that this probably would've been easier with shell's equivalent of regex, but I didn't want to take the time to dig around (and now I'm paying the price). Anyway:
sudobool=0
sudoCount=0
for i in `cat /var/log/auth.log`;
do
for word in $i;
do
if $word == "sudo:"
then
echo "sudo found"
sudobool=1;
sudoCount=`expr $sudoCount + 1`;
fi
done
sudobool=0;
done
echo "There were " $sudoCount " attempts to use sudo, " $sudoFailCount " of which failed."
So, my understanding of the code I've written: read auth.log and split it up line by line, which are stored in i. Each word in i is checked to see if it is sudo:, if it is, we flip the bool and increment. Once we've finished parsing the line, reset the bool and move to the next line.
However, judging by my output, the shell is trying to execute the individual words of the log file, typically returning '$word : not found'.
why don't you use grep for this?
grep sudo /var/log/auth.log
if you want a count pipe it to wc -l
grep sudo /var/log/auth.log | wc -l
or still better use -c option to grep, which prints how many lines were found containing sudo
grep -c sudo /var/log/auth.log
or maybe I am missing something simple here?
EDIT: I saw $sudoFailCount after scrolling, do you want to count how many failed attempts were made to use sudo ?? You have not defined any value for $sudoFailCount in your script, so it will print nothing. Also you are missing the test brackets [[ ]] around your if condition checking
Expanding on Sudhi's answer, here's a one-liner:
$ echo "There were $(grep -c ' sudo: ' /var/log/auth.log) attempts to use sudo, $(grep -c ' sudo: .*authentication failure' /var/log/auth.log) of which failed."
There were 17 attempts to use sudo, 1 of which failed.
Your error message arises from a lack of syntax in your if statement: you need to put the condition in [[brackets]]
Using the pattern matching in bash:
#!/bin/bash
sudoCount=0
while read line; do
sudoBool=0
if [[ "$line" = *sudo:* ]]; then
sudoBool=1
(( sudoCount++ ))
# do something with sudobool ?
fi
done < /var/log/auth.log
echo "There were $sudoCount attempts to use sudo."
I'm not initimately familiar with the auth.log -- what is the pattern to determine success or failure?

Resources