Here is my code
bash-3.2$ cat nexus.ksh
#!/usr/bin/ksh
LSEARCH=$(ldapsearch -p 389 -x -D "cn=xx" -w xxxx -b "ou=access,ou=nexus,ou=applications,o=xxx,c=xx" cn=$1 | grep -i uid=$2)
echo ldap search output is "${LSEARCH}"
if [ "$LSEARCH" -eq " " ]; then
echo " User is not present in ACL group...Adding User to ACL group"
else
echo "User is present in ACL Group"
fi
output:
bash-3.2$ ./nexus.ksh acl.LINK_ODI_1 xxxx
ldap search output is uniquemember: uid=xxx,ou=people,ou=access,ou=nexus,ou=applications,o=xxxx,c=
./nexus.ksh[4]: uniquemember: uid=xxx,ou=people,ou=access,ou=nexus,ou=applications,o=xxx,c=: bad number
User is present in ACL Group
can you tell where i am wrong ?
The -eq test compares numeric values. Since $LSEARCH has non-digit characters, it's causing your error.
Switch to [ "$LSEARCH" = " " ] or better yet [ -n "$LSEARCH" ] to test if $LSEARCH has nonzero length,
Handy reference for ksh conditional expressions: http://www.well.ox.ac.uk/~johnb/comp/unix/man_ksh.html#condexp
if [ "$LSEARCH" -eq " " ]; then
In Korn shell, the -eq operator is for numeric values, not strings. For strings, you should use =, as per the following transcript:
pax$ [ "pax diablo" -eq "pax diablo" ] && echo equal
ksh: [: pax diablo: arithmetic syntax error
pax$ [ "pax diablo" = "pax diablo" ] && echo equal
equal
pax$ [ 42 -eq 42 ] && echo equal
equal
As an aside, you may want to look into using the return value from ldapsearch rather than trying to parse the output (which is more likely to change). One way to achieve this is to do the search, ignoring output, and check the return code:
ldapsearch whatever >/dev/null 2>&1
rc=$? ; [ $rc -ne 0 ] && echo ldapsearch failed with error $rc
Related
I have a sample logic. By calculation, it is -2 > 0 . This is a false condition and I get no result, but I am getting the value as abcd.
#!/bin/bash
Val1=1
Val2=1
Val3=2
Name=abcd
log=/tmp/log
if [ "$((Val1-(Val2 + Val3))) -ge 0" ] ; then echo "$Name" | tee -a "$log"; fi
I have verified on ShellCheck, and it is giving me this message. I couldn't get how to fix this?
$ shellcheck myscript
Line 7:
if [ "$((Val1-(Val2 + Val3))) -ge 0" ] ; then echo "$Name" | tee -a "$log"; fi
^-- SC2157: Argument to implicit -n is always true due to literal strings.
If you use [ 'a string' ], that's the same as [ -n 'a string' ]: it checks if the parameter is non-empty. You're providing the argument "$((Val1-(Val2 + Va3))) -ge 0", which evaluates to the string "-2 -ge 0". "Implicit -n" means that the shell really checks
if [ -n "-2 -ge 0" ]
and that is always true, because that's not an empty string.
The reason is your quoting. This would work instead:
if [ "$((Val1-(Val2 + Val3)))" -ge 0 ]
Strictly speaking, the quotes aren't necessary, but they don't hurt, either.
Or, since you're using Bash, you could use an arithmetic conditional:
if ((Val1 - (Val2 + Val3) > 0))
I figured after posting the question
#!/bin/bash
Val1=1
Val2=1
Val3=2
Name=abcd
log=/tmp/log
if [ "$((Val1-(Val2 + Val3)))" -ge 0 ] ; then echo "$Name" | tee -a "$log"; fi
Usually i only use [[ for all kinds of test cases, because it's the most advanced way and it's more safe to use (Regex, ...).
I know that [[ executes different code than [, but according to the manpage and various documentations, it should at least handle options like "-n" the same way, but it doesn't.
-n STRING the length of STRING is nonzero
VAR=
if [[ -n $VAR ]]
then
echo "\$VAR is nonzero"
else
echo "\$VAR is zero"
fi
$VAR is zero
VAR=
if [ -n $VAR ]
then
echo "\$VAR is nonzero"
else
echo "\$VAR is zero"
fi
$VAR is nonzero
How is this even possible?
bash 4.1.2(1)
I think that your problem is related to quotes.
When you use [ -n $VAR ] the command that is executed won't contain any argument where $VAR should be:
$ set -x
$ [ -n $VAR ]
+ '[' -n ']'
This means that you are essentially testing whether the string -n is non-empty, because the following two tests are equivalent:
[ string ] # is a shorthand for
[ -n string ] # which is always true!
If you use quotes, then you get different behaviour:
$ [ -n "$VAR" ]
+ '[' -n '' ']'
Now you are testing whether the variable is non-empty, so you get the expected behaviour.
Quoting. You have to quote variables that you use in [:
$ VAR=
$ [ -n $VAR ]
$ echo $?
0
$ [ -n "$VAR" ]
$ echo $?
1
I have small shell script which is used to test the condition whether used is logged in or not using if condition.
#!/bin/bash
if [ $# -ne 1 ]
then
echo "Argument required"
echo "Usage: on user"
else
user="$1"
if who | grep ^"$user " > /dev/null
then
echo "$user is logged in"
else
echo "$user is not logged in"
fi
fi
This would be working correctly.
Now here is my question: if i try this if condition like below method means shell terminal through the error.
if [ who | grep ^"$user " > /dev/null ]
> Error ./user.sh: line 10: [: missing `]'
grep: ]: No such file or directory
could you please some tell what is the difference between these two test condition?
In simple words, the [ or test tests the results of expression, not command list.
Here is the syntax of test and if:
test expr
[ expr ]
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
Then in if construct, it can be followed by a commmand list.
So in if who | grep ^"$user " > /dev/null, it executes the command who | grep ^"$user " > /dev/null, then test the return status of the command.
But in if [ who | grep ^"$user " > /dev/null ], it first executes the command [ who | grep ^"$user " > /dev/null ], but because of the |(pipeline), the commmand will be parsed as two parts:
1st: [ who, which will complain: "line 10: [: missing `]'"
2nd: grep ^"$user " > /dev/null ] which will complain: "grep: ]: No such file or directory".
As for the format of the expression of the [ or test:
refer to The classic test command. And the main four expressoins are:
file tests, string tests, arithmetic tests, misc tests.
Use a function.
#!/bin/bash
logged_in () { who | grep ^"$1 " > /dev/null; }
if [ $# -ne 1 ]
then
echo "Argument required"
echo "Usage: on user"
else
user="$1"
if logged_in "$user"
then
echo "$user is logged in"
else
echo "$user is not logged in"
fi
fi
I am new in shell script, trying to catch the return value of a program, and do something with it.
I have this script below
#!/bin/sh
if [ $# !=2 ] ; then
echo "Usage : param1 param2 "
exit 1;
elif [ $# -eq 2 ]; then
./callprogram
$out = $?
echo "$out"
fi
if [ $out==0 ]; then
echo "out ok"
fi
It keeps getting me error of
"[: 11: 0: unexpected operator
out ok
I have no clue why line 11 is wrong. if I remove "fi", it will promt that it needs "fi". Can anyone help with this matter?
Thank you
You need a space after the [ and you need to use -eq (equals) or -ne (not equals) to compare numbers in your if-statement.
To assign a variable use out=$?, not $out = $?. There should be no spaces on either side of the = sign.
Try this:
if [ $# -ne 2 ] ; then
echo "Usage : param1 param2 "
exit 1
elif [ $# -eq 2 ]; then
./callprogram
out=$?
echo "$out"
fi
if [ $out -eq 0 ]; then
echo "out ok"
fi
Change:
if [ $out==0 ]; then
to:
if [ $out = 0 ]; then
add spaces, and change '==' to '='. Note, that bash, executed as a bash accepts ==. But if you run is as a sh it will say "unexpected operator".
Why:
The [ is a command (or symlink to test binary, depending on your OS and shell). It expects $out and == and 0 and ] to be separate command arguments. If you miss the space around them, you have one argument $out==0.
BTW:
It's safer to always enquote the variables like that:
if [ "$var" ......
instead of
if [ $var
because when variable is empty, then you can get another error because of wrong number of arguments (no argument instead of empty string).
You have several problems. The one that is giving you the error is that you need a space after != on
if [ $# != 2 ]
(although -ne would be better than !=). It appears that you are calling the script with 11 arguments, and then calling [ with the arguments 11 !=2, and it does not know what to do with !=2 because you meant != 2 but forgot the space. Also, you want
out=$?
on the assignment (no $ on the LHS)
and
if [ $out = 0 ]
on the comparison. (Spaces around the operator, which is '=' instead of '=='. '==' will work on many shells, but '=' works in more shells.)
But your script would be better written without the explicit reference to $?
#!/bin/sh
if test $# != 2; then
echo "Usage: $0 param1 param2 " >&2 # Errors go to stderr, not stdout
exit 1;
fi
# you know $# is 2 here. No need to check
if ./callprogram; then
echo "out ok"
fi
I am a new student to bash scripting, and I am stumped on an assignment question.
I was wondering if there is an easy way to determine whether a users' input is an integer or not. More specifically, if a user is prompted to input an integer, is there a quick check to validate?
One way is to check whether it contains non-number characters. You replace all digit characters with nothing and check for length -- if there's length there's non-digit characters.
if [[ -n ${input//[0-9]/} ]]; then
echo "Contains letters!"
fi
Another approach is to check whether the variable, evaluated in arithmetic context, is equal to itself. This is bash-specific
if [[ $((foo)) != $foo ]]; then
echo "Not just a number!"
fi
This is kind of a kludge, it's using -eq for something other then what it was intended, but it checks for an integer, if it doesn't find an int it returns both an error which you can toss to /dev/null and a value of false.
read input
if [[ $input ]] && [ $input -eq $input 2>/dev/null ]
then
echo "$input is an integer"
else
echo "$input is not an integer or not defined"
fi
You can test by using Regular expression
if ! [[ "$yournumber" =~ ^[0-9]+$ ]] ;
then exec >&2; echo "error: Not a number"; exit 1
fi
I found this post http://www.unix.com/shell-programming-scripting/21668-how-check-whether-string-number-not.html that talks about this.
If your input does not need to check if there is a +/- on the number, then you can do:
expr $num + 1 2> /dev/null
if [ $? = 0 ]
then
echo "Val was numeric"
else
echo "Val was non-numeric"
fi
Here is another way of doing it. It's probably a bit more elaborate than needed in most cases, but would handle decimals also. I had written the below code to get rounded number. It also checks for numeric input in the process.
#--- getRound -- Gives number rounded to nearest integer -----------------------
# usage: getRound <inputNumber>
#
# echos the rounded number
# Best to use it like:
# roundedNumber=`getRound $Number`
# check the return value ($?) and then process further
#
# Return Value:
# 2 - if <inputNumber> is not passed, or if more arguments are passed
# 3 - if <inputNumber> is not a positive number
# 0 - if <inputNumber> is successfully rounded
#
# Limitation: Cannot be used for negative numbers
#-------------------------------------------------------------------------------
getRound (){
if [ $# -ne 1 ]
then
exit 2
fi
#--- Check if input is a number
Input=$1
AB=`echo A${Input}B | tr -d [:digit:] | tr -d '.'`
if [ "${AB}" != "AB" ] #--- Allow only '.' and digit
then
exit 3
fi
DOTorNone=`echo ${Input} | tr -d [:digit:]` #--- Allow only one '.'
if [ "${DOTorNone}" != "" ] && [ "${DOTorNone}" != "." ]
then
exit 3
fi
echo $Input | awk '{print int($1+0.5)}' #--- Round to nearest integer
}
MyNumber=`getRound $1`
if [ $? -ne 0 ]
then
echo "Empty or invalid input passed"
else
echo "Rounded input: $MyNumber"
fi
This one works for me, handling empty input case.
if [ $input -eq $input 2>/dev/null -o $input -eq 0 2>/dev/null ]
then
echo Integer
else
echo Not an integer
fi