Below is not working when I am trying to access exported variable on remote server under if loop:
VAR=`grep pattern ./checklist | cut -f7`
echo "Port number to be checked for service is $VAR" #working fine
export VAR
ssh -tTq user#node <<EOF
echo "checking service on \`hostname\`";
echo "export value received is $VAR"
echo \$(ps -ef | grep -v grep | grep port=$VAR | wc -l)
if [ \$(ps -ef | grep -v grep | grep port=$VAR | wc -l) == 0 ];
then
echo "service is DOWN"
elif [ \$(ps -ef | grep -v grep | grep port=\$VAR | wc -l) == 1 ];
then
echo "Service is Up"
else
echo "Multiple instances running of selected service"
fi
EOF
Output received of if loop is not as expected:
Multiple instances running of selected service
+ '[' 1 == 2 ']'
instead of 1 == 1 condition match
Found the answer by myself.
In the above question I have missed \ before $VAR by mistake in elif condition.
LL: Strong/single quotes ' should be avoided for the cmds to be executed on remote host when using export variables via ssh.
Avoid using \ on under while calling export variable present between << EOF ..... EOF. (In above example $VAR)
Related
So I have this BASH script and what i want to do is, reach out to the servers. Check the used % of a directory. If it is higher than my set threshold (90) then print that server name to another file on the server where the script has been run from.
What it is doing is printing the first server name twice in to the file so it looks like
server1
server2
Here is my script ... I don't see why it would be going around in a loop to that first server twice
#!/bin/bash
SERVERS="server1
server2"
for i in $SERVERS; do
ssh $SERVERS "
df -h | grep var | awk '{print \$4}' | sed 's/%//g' > /home/user/space.txt
RESULTS=\$(grep -E "1[5-9]" /home/user/space.txt)
THRESHOLD=90
if [[ \$RESULTS -lt \$THRESHOLD ]]; then
exit 1;
elif [[ \$RESULTS -gt \$THRESHOLD ]]; then
hostname;
fi
" >> /home/user/problem.txt
done
Try this,
#!/bin/bash
SERVERS="server1
server2"
for i in $SERVERS; do
ssh "$i" "
df -h | grep var | awk '{print \$4}' | sed 's/%//g' > /home/user/space.txt
RESULTS=\$(grep -E "1[5-9]" /home/user/space.txt)
THRESHOLD=90
if [[ \$RESULTS -lt \$THRESHOLD ]]; then
exit 1;
elif [[ \$RESULTS -gt \$THRESHOLD ]]; then
hostname;
fi
" >> /home/user/problem.txt
done
I do not quite understand what the following if-statement actually does, in the sense of what the condition outputs could possibly be:
if linux-command-1 | linux-command-2 | linux-command-3 > /dev/null
I understand the execution as the following:
Linux Command 1 gets executed, it's output is PIPED into Linux-Command-2 as input.
Linux Command 2 gets executed with LC1's input, it's output is PIPED into Linux-Command-3.
Linux Command 3 gets executed with LC2's input, it's output is redirected into /dev/null, basically doesn't appear.
But what about the actual if-statement? What's responsible for it becoming true or false?
To further elaborate, here's an example with actual commands:
if ps ax | grep -v grep | grep terminator > /dev/null
then
echo "Success"
else
echo "Fail"
fi
I do know that the functionality behaves in the way that if any output occurs (Process is running) in that execution the condition is True, if nothing occurs (Process not running), the condition is False.
But I don't understand why or how it's coming to that conclusion? Is the shell if statement always expecting a string output as True?
I've also just discovered pgrep but the question would also remain if the statement were
if pgreg -f terminator > /dev/null
In your case you are testing the exit status of grep itself, which will return false (1) if there was no match and true (0) if there was one
if ps ax | grep -v grep | grep terminator > /dev/null
then
echo "Success"
else
echo "Fail"
fi
you could put a "-q" instead of redirection to /dev/null
if ps ax | grep -v grep | grep -q terminator
then
echo "Success"
else
echo "Fail"
fi
I would execute my commad and test the $?
ps ax | grep -v grep | grep terminator
if [ $? -eq 0 ]; then
echo 'it is ok'
else
echo 'is is ko'
fi
If you do:
if linux-command-1 | linux-command-2 | linux-command-3 > /dev/null
only the result of the last command matter
if everything is important put "&&" instead
if ps -ae | grep 'bash' | grep 'pty0' && ls . >/dev/null; then
echo "bash is in the house"
fi
that will fail because there is no not_exist
if ps -ae | grep 'bash' | grep 'pty0' && ls not_exist >/dev/null; then
echo "bash is in the house"
fi
How I can get an output message which is "1" or "0" of an already running file?
I mean if i have a .jar file and i tun it by this command java -jar [FILENAME].jar, how i can output a status number( 0 if it is not running or 1 if is running)
N.B: I only want the number as an output message. In a bash script as variable.
i think you are expecting something like this,
[ $(ps -ef | grep "[FILENAME].jar" | grep -v "grep" | wc -l) -gt 0 ] && echo "1" || echo "0"
if need bit more detailed version, then below will suit i guess,
if [ $(ps -ef | grep "[FILENAME].jar" | grep -v "grep" | wc -l) -gt 0 ];then
echo "1"
else
echo "0"
fi
I am trying to run a few bash scripts continually when I am logged in to my Linux Mint install. Adding them to startup applications doesnt appear to work, because they are not always running when I check. I also dont want to create multiple instances of the scripts so adding them to my .bashrc or a cronjob seems to be out. Any other suggestions?
An example script (warns me when my battery is below 30%):
#!/bin/bash
while :
do
#echo "starting script: $(date)">>battery_log
percent=$(upower -i /org/freedesktop/UPower/devices/battery_BAT0| grep -E "percentage" | grep -o '[0-9]\+')
cpu_temp=$(cat /sys/class/thermal/thermal_zone0/temp | awk '{print "deg C: "$1/1000}')
discharge=$(upower -i /org/freedesktop/UPower/devices/battery_BAT0| grep -E "state")
is_discharging=$(echo $discharge | grep -c discharging)
#echo "$percent"
#echo "$cpu_temp"
#echo hello | grep -c he
#if [echo $discharge | grep -c discharging -gt 0 ]; then
#echo "success"
#fi
#echo "$discharge"
if [ "$is_discharging" -gt 0 ]; then
echo "---discharging: $(date)">>battery_log
if [ "$percent" -lt 30 ]; then
#exec 2>>/home/king/Scripts/battery_log.txt
export DISPLAY=:0
#export XAUTHORITY=~otheruser/.Xauthority
#kdialog --msgbox "$(upower -i /org/freedesktop/UPower/devices/battery_BAT0| grep -E "state|to\ full|percentage") \n cpu temp: $(cat /sys/class/thermal/thermal_zone0/temp | awk '{print "deg C: "$1/1000}')"
kdialog --title "Low Battery" --passivepopup "$(upower -i /org/freedesktop/UPower/devices/battery_BAT0| grep -E "state|to\ full|percentage") \n cpu temp: $(cat /sys/class/thermal/thermal_zone0/temp | awk '{print "deg C: "$1/1000}')" 20
fi
fi
sleep 300 #5min
done
Before you run the script, check if an instance of your script is already running.
pgrep script.sh.
If it's already running, then you can exit, otherwise continue the script.
pgrep script.sh && exit should do the trick.
Currently I am trying to execute a bash file in a crontab. However, the command by itself is not working, this is the command.
for ip in $(seq 3 80); do for ip2 in $(seq 9 254); do count=$(ping -c 1 192.168.$ip.$ip2 | grep icmp* | wc -l) if [ $count -eq 0 ]; then echo "Host unreachable" else php /var/www/phpfile.php 192.168.$ip.$ip2 > 192.168.$ip.$ip2.txt; done; done
The error that the console is showing when I execute this command is this:
if: Command not found
I already checked the spaces between the brackets, I also tried to remove them, but none of those solutions have worked. Can you please tell me what is wrong with my command? What am I missing?
Thank you so much in advance.
You are missing a fi and some ;, Try this:
for ip in $(seq 3 80); do for ip2 in $(seq 9 254); do count=$(ping -c 1 192.168.$ip.$ip2 | grep icmp* | wc -l); if [ $count -eq 0 ]; then echo "Host unreachable"; else php /var/www/phpfile.php 192.168.$ip.$ip2 > 192.168.$ip.$ip2.txt;fi; done; done
It's better (for readability) to break codes into multiple lines insead of putting them all in a single line:
for ip in $(seq 3 80); do
for ip2 in $(seq 9 254); do
count=$(ping -c 1 192.168.$ip.$ip2 | grep icmp* | wc -l)
if [ $count -eq 0 ]; then
echo "Host unreachable"
else php /var/www/phpfile.php 192.168.$ip.$ip2 > 192.168.$ip.$ip2.txt;
fi
done
done
At the moment, your "one-line" script is totally unreadable, so it's no surprise that it contains errors. Change it to this:
#!/bin/sh
for ip in $(seq 3 80); do
for ip2 in $(seq 9 254); do
dest="192.168.$ip.$ip2"
if ping -c 1 "$dest" | grep -q 'icmp*'; then
php /var/www/phpfile.php "$dest" > "$dest".txt
else
echo "Host unreachable"
fi
done
done
and call it from your crontab.
I have removed the useless use of grep | wc -l, in place of using grep -q, which returns success if the pattern is matched.
Just since no one else seemed to comment on this.
The reason you got if: Command not found as an error is that the body of your inner loop:
count=$(ping -c 1 192.168.$ip.$ip2 | grep icmp* | wc -l) if [ $count -eq 0 ]; then echo "Host unreachable" else php /var/www/phpfile.php 192.168.$ip.$ip2 > 192.168.$ip.$ip2.txt
was being seen by the shell as a single command and not two commands.
Specifically it was being see as (cleaned up to make it more obvious):
count=$(command) if arg1 arg2 arg3 > outfile
Which then made if the command name (and count a variable set in the environment for that if command) and not, as you expected, a shell keyword akin to how this works:
$ printenv | grep FOO
$ FOO=bar printenv | grep FOO
FOO=bar