Bash error echo a command - bash

I have a problem. I need to show a echo from a while, I use two echo the first one work but the second it give a error.
#!/bin/bash
conexiuni="/tmp/conexiuni"
if [ "$1" != "" ]; then
netstat -tuan | grep $1 | grep ESTAB | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n > $conexiuni
else
netstat -tuan | grep ESTAB | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n > $conexiuni
fi
cat $conexiuni | while read line
do
con=`echo ''$line'' | awk '{print $1}'`
ip=`echo ''$line'' | awk '{print $2}'`
if [ "$con" -gt "4" ]; then
`echo -e "$ip" >> /var/log/drop_sc_ip`
`echo -e "$ip"`
fi
done
if [ -f "$conexiuni" ];
then
`rm -rf $conexiuni`
fi
The error is :
./show_conn: line 15: 8.97.80.2: command not found
./show_conn: line 15: 8.76.109.13: command not found
./show_conn: line 15: 8.33.15.2: command not found
./show_conn: line 15: 9.118.226.3: command not found

You can write this part without the backticks:
if [ "$con" -gt "4" ]; then
echo -e "$ip" >> /var/log/drop_sc_ip
echo -e "$ip"
fi
also same in this part:
rm -rf $conexiuni
with the backticks, it first executes what is inside the backticks and then tries to execute the output of the backticks.
and change the loop:
while read con ip
do
if [ "$con" -gt "4" ]; then
echo -e "$ip" >> /var/log/drop_sc_ip
echo -e "$ip"
fi
done < $conexiuni

Related

unexpected output in docker container

I have below script to get values from config:
#!/bin/bash
while read -u10 line
do
if echo $line | grep -v -e "^#" -e "^$" | grep -F "=" &>/dev/null
then
varname=$(echo "$line" | cut -f1 -d '=')
export $varname=$(echo "$line" | cut -f2 -d '=')
fi
done 10< ./config
echo $a
My config like below:
a="b"
when at my host, it print a as b, but in container, it print a as "b".
Could anyone know why?

if statement function to many argumnets

I've overlooked my program for any mistakes and can't find any. Usually when I run into a mistake with BASH the interpreter is off on where the mistake is. I'm trying to customize this script from SANS InfoSec Using Linux Scripts to Monitor Security. Everything is fine until the part where the check function looks at the different protocols. When I uncomment them I get the error: ./report: line 41: [: too many arguments. Here is the program...
#!/bin/bash
if [ "$(id -u)" != "0" ]; then
echo "Must be root to run this script!"
exit 1
fi
##### CONSTANTS -
report=/home/chron/Desktop/report.log
#router=/home/chron/Desktop/router.log
red=`tput bold;tput setaf 1`
yellow=`tput bold;tput setaf 3`
green=`tput bold;tput setaf 2`
blue=`tput bold;tput setaf 4`
magenta=`tput bold;tput setaf 5`
cyan=`tput bold;tput setaf 6`
white=`tput sgr0`
##### FUNCTIONS -
pingtest() {
ping=`ping -c 3 localhost | tail -2`
loss=`echo $ping | cut -d"," -f3 | cut -d" " -f2`
delay=`echo $ping | cut -d"=" -f2 | cut -d"." -f1`
if [ "$loss" = "100%" ]; then
echo -n $red$1$white is not responding at all | mail -s'REPORT' localhost
echo 'You have mail in /var/mail!'
echo `date` $1 is not responding at all >> $report
elif [ "$loss" != "0%" ]; then
echo $yellow$1$white is responding with some packet loss
else
if [ "$delay" -lt 100 ]; then
echo $green$1$white is responding normally
else
echo $yellow$1$white is responding slow
fi
fi
}
check() {
if [ "$2" != "" -a "$2" $3 ] ; then
echo -n $green$1$white' '
else
echo -n $red$1$white' '
echo `date` $1 was not $3 >> $report
fi
}
##### __MAIN__ -
pingtest localhost # hostname or ip
echo "Server Configuration:"
check hostname `hostname -s` '= localhost'
check domain `hostname -d` '= domain.com'
check ipaddress `hostname -I | cut -d" " -f1` '= 10.10.0.6'
check gateway `netstat -nr | grep ^0.0.0.0 | cut -c17-27` '= 10.10.0.1'
echo
echo "Integrity of Files:"
check hostsfile `md5sum /etc/hosts | grep 7c5c6678160fc706533dc46b95f06675 | wc -l` '= 1'
check passwd `md5sum /etc/passwd | grep adf5a9f5a9a70759aef4332cf2382944 | wc -l` '= 1'
#/etc/inetd.conf is missing...
echo
#echo "Integrity of Website:"
#check www/index.html `lynx -reload -dump http://<LOCALIP> 2>&1 | md5sum | cut -d" " -f1 '=<MD5SUM>'
#echo
echo "Incoming attempts:"
#lynx -auth user:password -dump http://10.10.0.1 >> $router 2>&1
check telnet `grep \ 23$ $PWD/router.log | wc -l` '= 0'
check ftp `grep \ 21$ $PWD/router.log | wc -l` '= 0'
check ssh `grep \ 22$ $PWD/router.log | wc -l` '=0'
check smtp `grep \ 25$ $PWD/router.log | wc -l` '=0'
check dns `grep \ 53$ $PWD/router.log | wc -l` '=0'
echo
Some of the lines are commented out for later tweaking. Right now my problem is with the protocols. Not sure what's wrong because it looks like to me there are 3 arguments for the function.
In your last three calls to check, you are missing the required space between the operator and the operand.
check ssh `grep \ 22$ $PWD/router.log | wc -l` '=0'
check smtp `grep \ 25$ $PWD/router.log | wc -l` '=0'
check dns `grep \ 53$ $PWD/router.log | wc -l` '=0'
The final argument to all of these should be '= 0'.
However, this is not a good way to structure your code. If you really need to parameterize the comparison fully (all your calls use = as the operation), pass the operator as a separate argument. Further, written correctly, there is no need to pre-check that $2 is a non-empty string.
check() {
if [ "$2" "$3" "$4" ] ; then
printf '%s%s%s ' "$green" "$1" "$white"
else
printf '%s%s%s ' "$red" "$1" "$white"
printf '%s %s was not %s\n' "$(date)" "$1" "$3" >> "$report"
fi
}
Then your calls to check should look like
check hostname "$(hostname -s)" = localhost
check domain "$(hostname -d)" = domain.com
check ipaddress "$(hostname -I | cut -d" " -f1)" = 10.10.0.6
check gateway "$(netstat -nr | grep ^0.0.0.0 | cut -c17-27)" = 10.10.0.1
etc
Run your code through http://shellcheck.net; there are a lot of things you can correct.
Here is my other problem. I changed it up a bit just to see what's going on.
router=/home/chron/Desktop/router.log
check() {
if [ "$2" "$3" "$4" ]; then
printf "%s%s%s" "$green" "$1" "$white"
else
printf "%s%s%s" "$red" "$1" "$white"
printf "%s %s was not %s\n" "$(date)" "$1" $3" >> report.log
fi
check gateway "$(route | grep 10.10.0.1 | cut -c17-27)" = 10.10.0.1
check telnet "$(grep -c \ 23$ $router)" = 0
check ftp "$(grep -c \ 21$ $router)" = 0
check ssh "$(grep -c \ 22$ $router)" = 0
check smtp "$(grep -c \ 25$ $router)" = 0
check dns "$(grep -c \ 53$ $router)" = 0

Converting multiple lines of bash in to a single line

Is there any short and easy way to convert multiple lines of script in to a single line to be parsed in a eval command?
ie
getent group | cut -f3 -d":" | sort -n | uniq -c |\
while read x ; do
[ -z "${x}" ] && break
set - $x ; if [ $1 -gt 1 ]; then
grps=`getent group | nawk -F: '($3 == n) { print $1 }' n=$2 | xargs` ; echo "Duplicate GID ($2): ${grps}" ; fi done
one_line=`cat your_script_file | sed ":a s/[\]$//; N; s/[\]$//; s/\n/ /; t a ;"`
echo $one_line

BASH: Remove newline for multiple commands

I need some help . I want the result will be
UP:N%:N%
but the current result is
UP:N%
:N%
this is the code.
#!/bin/bash
UP=$(pgrep mysql | wc -l);
if [ "$UP" -ne 1 ];
then
echo -n "DOWN"
else
echo -n "UP:"
fi
df -hl | grep 'sda1' | awk ' {percent+=$5;} END{print percent"%"}'| column -t && echo -n ":"
top -bn2 | grep "Cpu(s)" | \sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | \awk 'END{print 100 - $1"%"}'
You can use command substitution in your first sentence (notice you're creating a subshell in this way):
echo -n $(df -hl | grep 'sda1' | awk ' {percent+=$5;} END{print percent"%"}'| column -t ):

BASH better way to monitor files

I've made a Bash script to monitor some server log files for certain data and my method probably isn't the most efficient.
One section specifically bugs me is that I have to write a newline to the monitored log so that the same line wont be read over continually.
Feedback would be greatly appreciated!
#!/bin/bash
serverlog=/home/skay/NewWorld/server.log
onlinefile=/home/skay/website/log/online.log
offlinefile=/home/skay/website/log/offline.log
index=0
# Creating the file
if [ ! -f "$onlinefile" ]; then
touch $onlinefile
echo "Name Date Time" >> "$onlinefile"
fi
if [ ! -f "$offlinefile" ]; then
touch $offlinefile
echo "Name Date Time" >> "$offlinefile"
fi
# Functions
function readfile {
# Login Variables
loginplayer=`tail -1 $serverlog | grep "[INFO]" | grep "joined the game" | awk '{print $4}'`
logintime=`tail -1 $serverlog | grep "[INFO]" | grep "joined the game" | awk '{print $2}'`
logindate=`tail -1 $serverlog | grep "[INFO]" | grep "joined the game" | awk '{print $1}'`
# Logout Variables
logoutplayer=`tail -1 $serverlog | grep "[INFO]" | grep "left the game" | awk '{print $4}'`
logouttime=`tail -1 $serverlog | grep "[INFO]" | grep "left the game" | awk '{print $2}'`
logoutdate=`tail -1 $serverlog | grep "[INFO]" | grep "left the game" | awk '{print $1}'`
# Check for Player Login
if [ ! -z "$loginplayer" ]; then
echo "$loginplayer $logindate $logintime" >> "$onlinefile"
echo "Player $loginplayer login detected" >> "$serverlog"
line=`grep -rne "$loginplayer" $offlinefile | cut -d':' -f1`
if [ "$line" > 1 ]; then
sed -i "$line"d $offlinefile
unset loginplayer
unset line
fi
fi
# Check for Player Logout
if [ ! -z "$logoutplayer" ]; then
echo "$logoutplayer $logoutdate $logouttime" >> "$offlinefile"
echo "Player $loginplayer logout detected" >> "$serverlog"
line=`grep -rne "$logoutplayer" $onlinefile | cut -d':' -f1`
if [ "$line" > 1 ]; then
sed -i "$line"d $onlinefile
unset logoutplayer
unset line
fi
fi
}
# Loop
while [ $index -lt 100 ]; do
readfile
done
Thanks!
instead of using multiple
tail -n 1 file
try the following construct:
tail -f file | while read line;do
echo "read: $line"
done
it will be much more reliable...and won't read the same line twice ;)
note: by using new processes of grep/awk/etc you are burning away processes...it's not that it is critical, but usually process creation is expensive...but if new lines occur rarely it's perfectly fine
where i want'ed to get is: if you are intrested, take a look at bash builting string manipulator function replace $(x/aa} ${x//aa} and friends..or try to use extended regexpes with grep

Resources