Code works fine until the last for loop.
It tries to login database. Either, it establish a successful connection with database or not, script gives output OK/NOT OK depending to the connection and then exit the shell script. What should I do to solve this?
#!/bin/bash
read -p 'Username: ' var_username
read -sp 'Password: ' var_password
filename="$1"
while read -r line; do
name=$(sed 's/#.*$//g; s/(.*$//g; s/=.*$//g; s/).*$//g')
done < "$filename"
#retval=$? | tail -n1|grep OK
for tns in $name
do
tnsping $tns
if [ $? -eq 1 ]; then
echo $tns 'tnsping i calismiyor' >>tnslatest.log
else
echo $tns 'tnsping i calisiyor' >>tnslatest.log
working_tns+=($tns)
fi
done
#The following lines do not work properly.#
for working in $working_tns
do
echo "exit" | sqlplus -L $var_username/$var_password#$working | grep
Connected > /dev/null
if [ $? -eq 0 ]
then
echo "OK"
else
echo "NOT OK"
fi
done
For example; my tnsnames.ora file contains 4 tns.
So, I want to have for output like OK or NOT OK in total.
Thanks in advance.
I'm trying to implement a bash script who supposed to search for a word in a Python script terminal output.
The Python script doesn't stop so "&" in the end of the command is needed but the "if [ $? == 0 ] ; then" condition doesn't work.
How it can be solved?
Thanks, Gal.
#!/bin/bash
#Check if Pixhawk is connected
PORT=/dev/ttyPixhawk
end=$((SECONDS+3))
not_exists=f
/usr/local/bin/mavproxy.py --daemon --non-interactive --master=$PORT | grep 'Failed' &> /dev/null &
while [ $SECONDS -lt $end ] ; do
if [ $? == 0 ] ; then
not_exists=t
fi
sleep 1
done
if [ $not_exists=t ] ; then
echo "Not Exists"
else
echo "Exists"
fi
kill $(pgrep -f '/usr/local/bin/mavproxy.py')
Bash doesn't know anything about the output of background commands. Check for yourself with [ 5444 -lt 3 ] & echo $?.
your if statement wouldn't work in any case because $? checks for the return value of the most recent previous command, which in this case is your while loop.
You have a few different options. If you're waiting for some output, and you know how long it is in the output until whatever target you're looking for occurs, you can have the python write to a file and keep checking on the file size with a timeout for failure.
You can also continue with a simple timed approach as you have where you just check the output after a few seconds and decide success or failure based on that.
You can make your python script actually end, or provide more error messages, or write only the relevant parts to file that way.
Furthermore, you really should run your script through shellcheck.net to notice more problems.
You'll need to define your goal and use case more clearly to get real help; all we can really say is "your approach will not work, but there are definitely approaches which will work"
You are checking the status of grep command output inside while loop using $?. This can be done if $? is the next command to be fired after grep and if grep is not a back-group process . But in your script, $? will return the status of while [$SECONDS -lt $end ]. You can try to re-direct the output to a temp file and check it's status
/usr/local/bin/mavproxy.py --daemon --non-interactive --master=$PORT | grep 'Failed' &> tmp.txt &
sleep 3
# If file exists and it's size is greater than 0, [ -s File] will return true
if [ -s tmp.txt ]; then
echo 'pattern exists'
else
echo 'pattern not exists'
fi
I have the following shell script in place to send out an email alert. When I only have the for loop everything works fine but when I try to add the if condition it does not seem to work and returns a null message body everytime. A snippet from the script is as below:
for host in $servers
do
connections=`ssh $host "netstat -a | grep ES | wc -l"`
echo "$connections" >> debug.log
echo "$host" >> debug.log
if [$connections -gt 0]
then
echo "------------------------------------------------------------------" >> $emailmessage
echo "Host: $host needs to be checked" >> $emailmessage
echo "------------------------------------------------------------------" >> $emailmessage
echo "$connections" >> $emailmessage
else
echo "Everything is fine"
fi
done
I always end up getting the line 21: [49: command not found error when i try to execute the script. I tried debugging but I figured out my script is not even getting inside the if loop.
Can someone please let me know what am I missing?
Thanks in advance.
/rd
There should be space around [ and ] also its better to put variable in quotes, so update your line as
...
if [ "$connections" -gt 0 ] ;
then
...
I would like to have the echo command executed when cat /etc/passwd | grep "sysa" is not true.
What am I doing wrong?
if ! [ $(cat /etc/passwd | grep "sysa") ]; then
echo "ERROR - The user sysa could not be looked up"
exit 2
fi
try
if ! grep -q sysa /etc/passwd ; then
grep returns true if it finds the search target, and false if it doesn't.
So NOT false (! false) == true.
if evaluation in shells are designed to be very flexible, and many times doesn't require chains of commands (as you have written).
Also, looking at your code as is, your use of the $( ... ) form of cmd-substitution is to be commended, but think about what is coming out of the process. Try echo $(cat /etc/passwd | grep "sysa") to see what I mean. You can take that further by using the -c (count) option to grep and then do if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then which works but is rather old school.
BUT, you could use the newest shell features (arithmetic evaluation) like
if ! (( $(grep -c "sysa" /etc/passwd) == 0 )) ; then ...`
which also gives you the benefit of using the c-lang based comparison operators, ==,<,>,>=,<=,% and maybe a few others.
In this case, per a comment by Orwellophile, the arithmetic evaluation can be pared down even further, like
if ! (( $(grep -c "sysa" /etc/passwd) )) ; then ....
OR
if (( ! $(grep -c "sysa" /etc/passwd) )) ; then ....
Finally, there is an award called the Useless Use of Cat (UUOC). :-) Some people will jump up and down and cry gothca! I'll just say that grep can take a file name on its cmd-line, so why invoke extra processes and pipe constructions when you don't have to? ;-)
I hope this helps.
I think it can be simplified into:
grep sysa /etc/passwd || {
echo "ERROR - The user sysa could not be looked up"
exit 2
}
or in a single command line
$ grep sysa /etc/passwd || { echo "ERROR - The user sysa could not be looked up"; exit 2; }
This one
if [[ ! $(cat /etc/passwd | grep "sysa") ]]; then
echo " something"
exit 2
fi
What am I doing wrong?
$(...) holds the value, not the exit status, that is why this approach is wrong. However, in this specific case, it does indeed work because sysa will be printed which makes the test statement come true. However, if ! [ $(true) ]; then echo false; fi would always print false because the true command does not write anything to stdout (even though the exit code is 0). That is why it needs to be rephrased to if ! grep ...; then.
An alternative would be cat /etc/passwd | grep "sysa" || echo error. Edit: As Alex pointed out, cat is useless here: grep "sysa" /etc/passwd || echo error.
Found the other answers rather confusing, hope this helps someone.
Here is an answer by way of example:
In order to make sure data loggers are online a cron script runs every 15 minutes that looks like this:
#!/bin/bash
#
if ! ping -c 1 SOLAR &>/dev/null
then
echo "SUBJECT: SOLAR is not responding to ping" | ssmtp abc#def.com
echo "SOLAR is not responding to ping" | ssmtp 4151112222#txt.att.com
else
echo "SOLAR is up"
fi
#
if ! ping -c 1 OUTSIDE &>/dev/null
then
echo "SUBJECT: OUTSIDE is not responding to ping" | ssmtp abc#def.com
echo "OUTSIDE is not responding to ping" | ssmtp 4151112222#txt.att.com
else
echo "OUTSIDE is up"
fi
#
...and so on for each data logger that you can see in the montage
at http://www.SDsolarBlog.com/montage
FYI, using &>/dev/null redirects all output from the command, including errors, to /dev/null
(The conditional only requires the exit status of the ping command)
Also FYI, note that since cron jobs run as root there is no need to use sudo ping in a cron script.
simply:
if ! examplecommand arg1 arg2 ...; then
#code block
fi
without any brackets.
On Unix systems that supports it (not macOS it seems):
if getent passwd "$username" >/dev/null; then
printf 'User %s exists\n' "$username"
else
printf 'User %s does not exist\n' "$username"
fi
This has the advantage that it will query any directory service that may be in use (YP/NIS or LDAP etc.) and the local password database file.
The issue with grep -q "$username" /etc/passwd is that it will give a false positive when there is no such user, but something else matches the pattern. This could happen if there is a partial or exact match somewhere else in the file.
For example, in my passwd file, there is a line saying
build:*:21:21:base and xenocara build:/var/empty:/bin/ksh
This would provoke a valid match on things like cara and enoc etc., even though there are no such users on my system.
For a grep solution to be correct, you will need to properly parse the /etc/passwd file:
if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then
# found
else
# not found
fi
... or any other similar test against the first of the :-delimited fields.
I'd expect to see in the answers the direct use of grep with -q option (as we don't care the result but need only the return code.)
if ! grep -qs "sysa" /etc/passwd; then
echo "ERROR - The user sysa could not be looked up" >&2
exit 2
fi
or (to use chained execution on fail)
grep -qs "sysa" /etc/passwd || {
echo "ERROR - The user sysa could not be looked up" >&2
exit 2
}
Better, because the opposite is wanted, there's option -v for that
if grep -qsv "sysa" /etc/passwd; then
echo "ERROR - The user sysa could not be looked up" >&2
exit 2
fi
or (to use chained execution on success)
grep -qsv "sysa" /etc/passwd && {
echo "ERROR - The user sysa could not be looked up" >&2
exit 2
}
Notes
I like redirecting error messages to stderr, but echo output to stdout, hence >&2
Taylor the search pattern, e.g something like '^sysa:' if it's full login.
The command
grep shutting log.log
returns nothing.
My script is as follows
#!/bin/bash
FAIL=`grep shutting log.log`
if [ "$FAIL"="Binary file log.log matches" ]; then
echo FOUND
else
echo NOT FOUND
fi
I'm expecting NOT FOUND but get FOUND
You have to put spaces around the = operator in an [ ... ] expression; what you have written is being interpreted as [ string ], which tests whether string is nonempty.
But you don't need backticks nor string comparison at all here. Try this instead:
if grep -q shutting log.log
then echo FOUND
else echo NOT FOUND
fi
(Thankfully, the systems that did not have the -q option to grep have long since gone to the great bit bucket in the sky.)
In your test you need spaces around the =:
#!/bin/bash
FAIL=`grep shutting log.log`
if [ "$FAIL" = "Binary file log.log matches" ]; then
echo FOUND
else
echo NOT FOUND
fi
See http://tldp.org/LDP/abs/html/comparison-ops.html