Bash script doesn't work as cronjob - bash

Hi i wrote the following bash script:
cat /home/xyz/wlandiscovery.sh
#!/bin/bash
DATE=`date +%d-%m-%Y__%H:%M:%S`
#Get the current standard interface e.g. eth0
INTERFACE=`route | grep '*' | awk '{print $8}'`
#Check if mac is available
if /usr/bin/arp-scan --interface $INTERFACE -l -r 5 | grep "xx:xx:xx:xx:xx:xx"
then
echo -e "$DATE AVAILABLE!" >> /home/xyz/wlandiscovery.log
else
echo -e "$DATE NOT AVAILABLE" >> /home/xyz/wlandiscovery.log
fi
exit 0
If i run this and the mac is available i get "AVAILABLE", if i disconnect the device it give "NOT AVAILABLE"...so run as expected.
But if i run it as Cronjob every 5 Minutes I get always "NOT AVAILABLE": (on a Debian system)
crontab -e
#......
*/5 * * * * /bin/bash /home/xyz/wlandiscovery.sh
Whats the problem here?

INTERFACE=`route | grep '*' | awk '{print $8}'`
On my system, route is /usr/sbin/route. /usr/sbin is most likely not in cron's PATH. Specify the full path:
INTERFACE=`/usr/sbin/route | awk '$2 == "*" {print $8}'`

Compare the command line output of the following on your Mac and Debian boxes:
INTERFACE=route | grep '*' | awk '{print $8}'
Is it the same? It should be in order to work.
Then, compare the command line output of:
/usr/bin/arp-scan --interface $INTERFACE -l -r 5 | grep "xx:xx:xx:xx:xx:xx"

Alright, now its working. seems that $PATH with crontab is not equal to $PATH in my Terminal prompt... if i do /sbin/route and /usr/bin/awk and /bin/grep it works.

Related

Why does bash return the file directory when using a back tick?

I'm running this series of commands
passwd=`wc -l /etc/passwd`
echo $passwd
Returns:
34 /etc/passwd
What do I need to do to this so that it will only show the output of wc -l?
Just read from standard input instead of giving wc a file name:
$ passwd=`wc -l < /etc/passwd`
$ echo "$passwd"
86
wc still outputs quite a bit of padding, but the file name is omitted (because wc has no idea what file the data comes from).
Using awk perhaps ?
$ passwd=$(wc -l /etc/passwd | awk '{print $1}')
$ echo $passwd
32
Using cut, from cut (GNU coreutils)
$ passwd=$(wc -l /etc/passwd | cut -d" " -f1)
$ echo $passwd
32
That's the default behaviour of wc:
ยป wc -l /etc/passwd
28 /etc/passwd
There is no way to tell wc not to output the filename.
wc returns also the filename, but there are other ways to do it. Some examples:
passwd=`wc -l /etc/passwd | grep -o [1-9]\*`
or
passwd=`wc -l /etc/passwd | cut -f1 -d' '`
(answer from this question: get just the integer from wc in bash)

List all cronjobs if there are any without superfluous info

Trying to output a list of cronjobs, not a list of users. The raw output of crontab -l is way too dirty and I can't seem to clean it up. I run this with sudo script.sh or su and then run it. I've tried invoking it sudo script.sh | grep -v no also. I'm mystified why this doesn't work:
#!/bin/bash
#Trying to show all cronjobs but no extraneous info
#
# This shows "no crontab for USER" for every USER without
# a crontab - I only want to see actual cronjobs, not a long
# list of users without crontabs
echo "Here is the basic output that needs manipulation:
"
for USER in `cat /etc/passwd | cut -d":" -f1`; do
crontab -l -u $USER
done
#
# grep -v fails me
# (grep'ing the output of the script as a whole fails also)
echo "
trying with grep -v no on each line:
"
for USER in `cat /etc/passwd | cut -d":" -f1`; do
crontab -l -u $USER | grep -v no
done
echo "
maybe with quotes around the no:
"
for USER in `cat /etc/passwd | cut -d":" -f1`; do
crontab -l -u $USER | grep -v "no"
done
# string manipulation - I can't even get started
echo "
And here I try to put the commmand output into a string so I can manipulate it further, and use an if/then/fi on the product:
"
for USER in `cat /etc/passwd | cut -d":" -f1`; do
STRING="$(crontab -l -u $USER | grep -v no)"
echo "STRING: $STRING"
done
BTW, is there an easier way to get code to format correctly here than pasting in 4 spaces at the beginning of each line? I must have experimented for 40 minutes. Not complaining, just asking.
crontab is wiring the "no crontab for user" to standard error. To get rid of those messages, you can run
crontab -l -u $USER 2>/dev/null
within your loop.
I would also suggest renaming USER into something else. The USER variable name is reserved, and should be set to your user (login) name. Generally, you should use lower case variable names, to avoid this sort of name clash.

commands not found when running script

I have a very basic script that keeps spitting back that the commands are not found. Ive looked all over this site and can not find an answer that works for me. The path to bash is correct. Ive checked the script with od. Ive run dos2unix. None of this helps me.
SCRIPT:
#!/bin/bash
HYBRISPROC=`ps -eo pid,command | grep [h]ybris | grep -v grep | awk '{print $1}'`
echo "Looking for Hybris..."
echo $HYBRISPROC
RESULTS:
./HybrisStopStart.sh: line 5: ps: command not found
./HybrisStopStart.sh: line 5: grep: command not found
./HybrisStopStart.sh: line 5: awk: command not found
./HybrisStopStart.sh: line 5: grep: command not found
Looking for Hybris...
Any ideas? If I run the command just on its own it works fine. Ive tried it as sudo as well and et the same results.
TIA
How about it?
#!/bin/bash
HYBRISPROC=`ps -eo pid,command | grep [h]ybris | grep -v grep | awk '{print $1}'`
echo "Looking for Hybris..."
echo "$HYBRISPROC"
(OR)
#!/bin/bash
HYBRISPROC="ps -eo pid,command | grep [h]ybris | grep -v grep | awk '{print $1}'"
echo "Looking for Hybris..."
bash -c "$HYBRISPROC"
(OR)
#!/bin/bash
HYBRISPROC="ps -eo pid,command | grep [h]ybris | grep -v grep | awk '{print $1}'"
echo "Looking for Hybris..."
eval "$HYBRISPROC"
TOTALY:
you can see the difference:
#!/bin/bash
LS=`ls -l`
echo $LS #nasty way
echo
echo "$LS" #good way
Try to add
PATH="$PATH:/usr/bin:/bin"
before code. Looks like bin directory is not on your path. So the commands are not found.

syntax error near unexpected token `&' (using "|&")

I have syntax error near unexpected token & in next :
in bash scripts its'go like this :
#!/bin/bash
var1=`(/usr/bin/time cdifonline -CD 186821 -ALL > /dev/null)|& grep real|awk '{print $2}'`
when i issue this command on cli i get good output, problem is when invoke this in script i can get any output from var1
./check_cdifonline.sh: command substitution: line 2: syntax error near unexpected token `&'
./check_cdifonline.sh: command substitution: line 2: `(/usr/bin/time cdifonline -CD 186821 -ALL >/dev/null) | & grep real | awk '{print $2}''
You can use the sequence |& to pipe both stdout and stderr from one process to another.
You cannot have a space between the | and the &. (csh and tcsh allow a space; bash does not.) I suspect you happen to be typing it without the space when you run the command interactively; the syntax is the same either way.
This:
foo |& bar
is shorthand for this:
foo 2>&1 | bar
UPDATE :
With bash 3.2.25, the |& token is not recognized; was added as a new feature in bash 4.1. Running your script with the older bash, I get the same error message you do.
To make your script compatible with older versions of bash, just do the equivalent redirection without using the |& operator:
#!/bin/bash
var1=`(/usr/bin/time cdifonline -CD 186821 -ALL > /dev/null) 2>&1 | grep real | awk '{print $2}'`
Further refinements: Use $(...) rather than `...`:
#!/bin/bash
var1=$((/usr/bin/time cdifonline -CD 186821 -ALL > /dev/null) 2>&1 | grep real | awk '{print $2}')
You can also incorporate the grep search into the awk command:
#!/bin/bash
var1=$((/usr/bin/time cdifonline -CD 186821 -ALL > /dev/null) 2>&1 | awk '/real/ {print $2}')
Warning: I have not thoroughly tested these beyond verifying that they run without syntax errors.
I still see no difference between |& and | &. Is it possible that /bin/bash is a different version than what you're running interactively? Try /bin/bash --version and echo $BASH_VERSION.
Try change to:
var1=$(/usr/bin/time cdifonline -CD 186821 -ALL >/dev/null | awk '/real/ {print $2}')
Thanks Keith I have no problems anymore you saved my day :) so the bash version was the problem and with avoiding of & I have no errors, thanks also for fine tuning :)
so this works with my bash version
#!/bin/bash
var1=`(/usr/bin/time cdifonline -CD 186821 -ALL > /dev/null) 2>&1 | grep real | awk '{print $2}'`

Shell script to kill a process

I need to implement a shell script that kills a process. The problem is that I need to do a conditional to be able to see if the process is running or not.
This is my code, but it is not working:
#!/bin/sh
if [ -x "MY_PROCCESS_NAME"]; then
killall MY_PROCCESS_NAME
else
echo "Doesn't exist"
fi
This is the error:
line 3: [: missing `]'
to check if a process is running on mac os x you can use:
pid=$(ps -fe | grep 'process name' | grep -v grep | awk '{print $2}')
if you want to reduce the number of shell scripts you can enclose one of the characters of the name of the process in square brackets:
pid=$(ps -fe | grep '[p]rocess name' | awk '{print $2}')
combined in your test this would look like:
pid=$(ps -fe | grep '[p]rocess name' | awk '{print $2}')
if [[ -n $pid ]]; then
kill $pid
else
echo "Does not exist"
fi
it's a little more complicated than you would need to do under linux as you generally have the 'pgrep' command, which is the rough equivalent of the 'ps -fe | grep ... | grep -v grep'
not sure if it would work in OSX, it works in ubuntu.
but as a one liner:
ps aux | awk '$11~/vim/ {PID = $2} END {if (PID) print "kill -9 "PID; else print "echo no process"}' | bash
what it does is it finds a process, in this case, vim and returns the kill -9 pid if no string is found it returns echo no process it then pipes the output to bash.

Resources