There are huge differences between ksh (and bash ) test expression and [ expression ] versus [[ expression ]].
The test and [ are the names of utilities (usually the same physical utility and almost always implemented as shell built-ins). But [[ and ]] are keywords in the Korn shell's grammar; not commands to be invoked.
In the following examples, assume that a script starts with:
Code:
#!/bin/ksh
op="-$1"
file="$2"
exp="$op $file"
(similar to what you had in your initial post), and continues with the commands included in the examples.
Example 1:
The commands:
Code:
if test "$exp";then echo true;else echo false;fi
if [ "$exp" ];then echo true;else echo false;fi
will both ALWAYS print true. Since the expansion of $exp is quoted, a single string is being passed to test. Therefore, this will test whether or not $exp expands to an empty string. Since it contains at least two characters, it is not an empty string. Therefore, it evaluates to true. These commands are logically treated as identical to the commands:
Code:
if test -n "$exp";then echo true;else echo false;fi
if [ -n "$exp" ];then echo true;else echo false;fi
Example 2:
Without the quotes:
Code:
if test $exp;then echo true;else echo false;fi
if [ $exp ];then echo true;else echo false;fi
will evaluate the operation specified by $op against the file specified by $file. As long as there aren't any IFS characters in the expansions of $op and $file, and <space> is included in IFS (so field splitting will separate $op and $file into separate arguments to test) this should do what you want.
Example 3:
If a filename contains any IFS characters, the code in Example 2 won't work, but the commands:
Code:
if test "$op" "$file";then echo true;else echo false;fi
if [ "$op" "$file" ];then echo true;else echo false;fi
will do what you want for any valid test op code.
Example 4:
The commands:
Code:
if [[ $op $file ]];then echo true;else echo false;fi
if [[ "$op" $file ]];then echo true;else echo false;fi
if [[ $op "$file" ]];then echo true;else echo false;fi
if [[ "$op" "$file" ]];then echo true;else echo false;fi
are all equivalent and will always give you a syntax error. Since [[ is a keyword (not the name of a utility), the shell itself recognizes that $op and $file are variables and doesn't perform field splitting or pathname expansion. Neither ksh nor bash accept a variable as an operator in the expression evaluated by [[ expression ]] and two variables can't be concatenated without an operator between them. So, you get a syntax error.
Example 5:
Since [[ doesn't do field splitting, the commands:
Code:
if [[ $exp ]];then echo true;else echo false;fi
if [[ "$exp" ]];then echo true;else echo false;fi
are treated as equivalent to:
Code:
if [[ -n "$exp" ]];then echo true;else echo false;fi
as in Example 1 above.
With sea's suggestion of using set -x (either using that as the 2nd line in your script, or by invoking your script with):
Code:
ksh -x script_name operator pathname
you'll be able to see how ksh handles each of these examples.
Last edited by Don Cragun; 12-23-2014 at 04:13 AM..
Reason: Fix ICODE tag that should have been a CODE tag.
These 5 Users Gave Thanks to Don Cragun For This Post:
my ultimate goal is to have a file test in a function with the test condition and file name fed in as parameters.
i placed the echo statement just before the test statement.
Code:
#!/bin/ksh
test_input()
{
Prmshn=${1}
InFLNm=${2}
echo "DEBUG: $Prmshn -- $InFLNm"
if test "$Prmshn" "$InFLNm" ; then
echo "$Prmshn $InFLNm input file is now available."
else
echo "$Prmshn $InFLNm input file is not available."
fi
}
#test_input -x /input/test.txt
test_input /input/test.txt
when i kept the -x in the function call i got this:
DEBUG: -x -- /input/test.txt
when i removed the -x from the function call, as suggested i got this message:
/scripts/testing/mks.ksh: test: argum/input/test.txt input file is not available.
my ultimate goal is to have a file test in a function with the test condition and file name fed in as parameters.
i placed the echo statement just before the test statement.
Code:
#!/bin/ksh
test_input()
{
Prmshn=${1}
InFLNm=${2}
echo "DEBUG: $Prmshn -- $InFLNm"
if test "$Prmshn" "$InFLNm" ; then
echo "$Prmshn $InFLNm input file is now available."
else
echo "$Prmshn $InFLNm input file is not available."
fi
}
#test_input -x /input/test.txt
test_input /input/test.txt
when i kept the -x in the function call i got this:
DEBUG: -x -- /input/test.txt
when i removed the -x from the function call, as suggested i got this message:
/scripts/testing/mks.ksh: test: argum/input/test.txt input file is not available.
Huh? Who suggested that you remove one of the two required parameters to your function?
There was a suggestion that you could invoke your script with:
Code:
ksh -x /scripts/testing/mks.ksh
to turn on tracing. And there was a suggestion that you could change your script to:
Code:
#!/bin/ksh
set -x
test_input()
{
Prmshn=${1}
InFLNm=${2}
echo "DEBUG: $Prmshn -- $InFLNm"
if test "$Prmshn" "$InFLNm" ; then
echo " $Prmshn $InFLNm input file is now available."
else
echo " $Prmshn $InFLNm input file is not available."
fi
}
test_input -x /input/test.txt
to enable tracing. Or, to make it easier to read and enable tracing, something like:
Code:
#!/bin/ksh
set -x
test_input() {
Prmshn=${1}
InFLNm=${2}
echo "DEBUG: $Prmshn -- $InFLNm"
if test "$Prmshn" "$InFLNm"
then echo " $Prmshn $InFLNm input file is now available."
else echo " $Prmshn $InFLNm input file is not available."
fi
}
test_input -x /input/test.txt
NOTE: I added a space in your echo commands before $Prmshn. Calling echo with a 1st argument that starts with a minus sign produces results that vary radically from system to system!
Using:
Code:
test_input -x /input/test.txt
as the last line in your script is a asking your function to determine whether or not /input/test.txt is an executable file. If you just want to know whether or not/input/test.txt is present on your system, use:
Code:
test_input -e /input/test.txt
If you want to know if /input/test.txt is present and is a regular file, use:
Code:
test_input -f /input/test.txt
If you want to know if /input/test.txt is present and is a directory, use:
Code:
test_input -d /input/test.txt
If you want to know if /input/test.txt is present and is readable, use:
I'm new to unix and the command line and am trying to learn different commands. I have a file (teledir.txt) that contains a name and phone number for 3 different people. I am writing a script that is to take two positional parameters and I typed out how it should behave:
if <name and number... (1 Reply)
Please see part of a shell script below.
#Move folder to HOT folder
echo " moving $PRE_OCR_DIR/$BATCHNAME to $HOT_FOLDER_DIR\n"
#chmod -R 777 $PRE_OCR_DIR/$BATCHNAME
mv $PRE_OCR_DIR/$BATCHNAME $HOT_FOLDER_DIR
I wish to write an if statement around the move
that if that if $BATCHNAME... (3 Replies)
Hi,
Is there a way to compare the value in if condition with a list of values.
eg . if ]
then
echo "it's a mammal"
else
echo "its not"
fi
Thanks! (8 Replies)
sorry but need help
http://i.investopedia.com/inv/articles/site/CalculationEMA.gif
trying to achieve ema
in script I have this syntax which errors
ema=` ;
the 0.153846154 ='s Smoothing Factor
really appreciate help (3 Replies)
Hi,
I am having a shell Script which i need to modify. I am new to shell scripting , needs help. The Logic which needs to be incorporated is as follows :-
The script need to check the length of first Line in a data fine and of the length of the file is > 130 then validated the input... (2 Replies)
hello everyone
i am beginner on shell scripting .and i am working on my project work on ad hoc network
i wrote a batch (.sh) to do a looping and execute a tcl script i wrote before in each iteration ..but i got this problem "
syntax error near unexpected token `('... (1 Reply)
I'm working on a function in a shell script I'm writing that will eventually take in and print out a list of vendor names and aliases (for my work) Here's the function in question:
addvendorandalias ()
{
echo
echo -n 'Would you like to create a new vendor list (y or n)? '
read answer... (3 Replies)
Hi Guys,
iīve a question ... but itīs a litte bit tricky:
iīve a 3 php-scripts which runīs via cron at night. These script reads an xml-file a writes it in an MySQL-DB.
I named them (for example here ) Script1 - Script3. The XML-Files i named xml1 - xml3.
Now, iīve build a Batch-file,... (10 Replies)
Hi All,
I am new to shell scripting.
I have a variable which holds a numeric value.I have to check whether this variable holds a value between(0- 8),(8-17)(17-24).How do i write this syntax using if in shell scripting.
Thanks
Vignesh (2 Replies)
I have a rather big script that i have written in ksh and it is falling over in two places with a 'test argument' error. I know this usually means that the if statement is not correct, but it is fine. I have looked through the rest of the script for any odd brackets or ` marks, but can't see... (2 Replies)