|
Programming C, bash, Python, Perl, PHP, Java, you name it. |
|
Thread Tools | Display Modes |
|
|||
Comparing strings with the shell
From test(1):
Code:
s1 = s2 True if the strings s1 and s2 are identical. s1 != s2 True if the strings s1 and s2 are not identical. s1 < s2 True if string s1 comes before s2 based on the ASCII value of their characters. s1 > s2 True if string s1 comes after s2 based on the ASCII value of their characters. Code:
$ if [ 'aaa' < 'aab' ] ; then echo stringwise smaller ; fi ksh: cannot open aab: No such file or directory Code:
$ if [ 'aaa' \< 'aab' ] ; then echo stringwise smaller ; fi ksh: [: <: unexpected operator/operand Then I remember that shells have built-in's commands that sometimes behave differently than the ones residing in /bin/ for example. Checking the shell test command From ksh(1): Code:
test expression [ expression ] test evaluates the expression and returns zero status if true, 1 if false, or greater than 1 if there was an error. It is normally used as the condition command of if and while statements. [snip] -n string string is not empty. -z string string is empty. string = string Strings are equal. string == string Strings are equal. string != string Strings are not equal number -eq number Numbers compare equal. The /bin/test executable instead of the ksh one works with escaping the '<': Code:
$ if /bin/test "aap" \< "aap2" ; then echo Smaller! ; fi Smaller! Code:
$ if /bin/test "aap2" > "aap" ; then echo Larger! ; fi Larger! $ if /bin/test "aap" > "aap" ; then echo Larger! ; fi Larger! $ ls -l aap -rw-r--r-- 1 adriaan adriaan 0 Dec 31 02:05 aap Code:
$ if /bin/test "aap" \> "aap" ; then echo Larger! ; fi $
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump |
|
|||
Two demo shell scripts that show the problem as well as the solution. The problematic one stringwise_less.sh:
Code:
#!/bin/sh #set -o posix if [ "X$1" = "X" ]; then prev_date="20151229" else prev_date="$1" fi cur_date=$(date "+%Y-%m-%d") cur_date=$(date "+%Y%m%d") show() { echo echo "Previous date : [$prev_date]" echo "Current date : [$cur_date]" cat <<END -----file list------------------------------------- $(ls -ltr) --------------------------------------------------- END } if [ "$prev_date" < "$cur_date" ]; then show echo "Previous date [$prev_date] < current date [$cur_date]" fi if [ "$prev_date" = "$cur_date" ]; then show echo "Previous date [$prev_date] = current date [$cur_date]" fi if [ "$prev_date" > "$cur_date" ]; then show echo "Previous date [$prev_date] > current date [$cur_date]" fi Code:
$ stringwise_less.sh 20141231 ./stringwise_less.sh[28]: cannot open 20151231: No such file or directory Previous date : [20141231] Current date : [20151231] -----file list------------------------------------- total 8 -rwxr--r-- 1 adriaan adriaan 739 Dec 30 23:59 stringwise_less.sh -rwxr--r-- 1 adriaan adriaan 764 Dec 31 01:24 stringwise_less2.sh -rw-r--r-- 1 adriaan adriaan 0 Dec 31 02:27 20151231 --------------------------------------------------- Previous date [20141231] > current date [20151231] $ rm 2015* $ stringwise_less.sh 20191231 ./stringwise_less.sh[28]: cannot open 20151231: No such file or directory Previous date : [20191231] Current date : [20151231] -----file list------------------------------------- total 8 -rwxr--r-- 1 adriaan adriaan 739 Dec 30 23:59 stringwise_less.sh -rwxr--r-- 1 adriaan adriaan 764 Dec 31 01:24 stringwise_less2.sh -rw-r--r-- 1 adriaan adriaan 0 Dec 31 02:29 20151231 --------------------------------------------------- Previous date [20191231] > current date [20151231] $ date Thu Dec 31 02:31:58 CET 2015 $ stringwise_less.sh 20151231 ./stringwise_less.sh[28]: cannot open 20151231: No such file or directory Previous date : [20151231] Current date : [20151231] -----file list------------------------------------- total 8 -rwxr--r-- 1 adriaan adriaan 739 Dec 30 23:59 stringwise_less.sh -rwxr--r-- 1 adriaan adriaan 764 Dec 31 01:24 stringwise_less2.sh --------------------------------------------------- Previous date [20151231] = current date [20151231] Previous date : [20151231] Current date : [20151231] -----file list------------------------------------- total 8 -rwxr--r-- 1 adriaan adriaan 739 Dec 30 23:59 stringwise_less.sh -rwxr--r-- 1 adriaan adriaan 764 Dec 31 01:24 stringwise_less2.sh -rw-r--r-- 1 adriaan adriaan 0 Dec 31 02:32 20151231 --------------------------------------------------- Previous date [20151231] > current date [20151231] $ Code:
$ grep test stringwise_less2.sh if /bin/test "$prev_date" \< "$cur_date" ; then if /bin/test "$prev_date" = "$cur_date" ; then if /bin/test "$prev_date" \> "$cur_date" ; then Code:
Note: A common mistake is to use ``if [ $foo = bar ]'' which fails if parameter ``foo'' is NULL or unset, if it has embedded spaces (i.e. IFS characters), or if it is a unary operator like `!' or `-n'. Use tests like ``if [ "X$foo" = Xbar ]'' instead.
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump Last edited by J65nko; 31st December 2015 at 01:54 AM. |
|
|||
Yes, I know that the Korn shell [[ .... ]] constructs allows it. On OpenBSD it also does and you don't need to quote it.
Code:
$ if [[ 'zzz' > 'aaa' ]]; then echo Greater ; fi Greater $ ls -l aaa ls: aaa: No such file or directory $ if [[ 'zzz' \> 'aaa' ]]; then echo Greater ; fi ksh: syntax error: `"zzz"' missing expression operator $ Code:
$ echo $SHELL /bin/sh $ uname FreeBSD $ if [[ 'zzz' > 'aaa' ]]; then echo Greater ; fi [[: not found $ ls -l aaa -rw-r--r-- 1 j65nko j65nko 0 Jan 1 16:39 aaa $ if [ 'zzz' > 'aaa' ]; then echo Greater ; fi Greater $ ls -l aaa -rw-r--r-- 1 j65nko j65nko 0 Jan 1 16:42 aaa $ rm aaa $ if [ 'zzz' \> 'aaa' ]; then echo Greater ; fi Greater $ ls -l aaa ls: aaa: No such file or directory $ Code:
[ A built-in equivalent of test(1).
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump |
|
||||
FYI, the < and > operators are not in POSIX
__________________
UNIX was not designed to stop you from doing stupid things, because that would also stop you from doing clever things. |
|
|||
I tried to enable POSIX mode but disabled that with #set -o posix (see the second post) when I found the POSIX documents.
While missing from POSIX test(1), these < and > operators are in POSIX expr(1). With Linux expr works: Code:
$ if expr 'zzz' \> 'aaa' ; then echo Greater ; fi Greater Quote:
Code:
$ if expr 'zzz' \> 'aaa' ; then echo Greater ; fi 1 Greater
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump Last edited by J65nko; 2nd January 2016 at 06:30 PM. |
|
|||
Yes, you are right. The GNU coreutils 8.21 expr on a Linux Mint live USB stick also does print out the result:
Code:
mint@mint ~ $ if expr 'zzz' \> 'aaa' ; then echo Greater ; fi 1 Greater Code:
mint@mint ~ $ if expr 'zzz' > 'aaa' ; then echo Greater ; fi Greater mint@mint ~ $ ls -l aaa -rw-r--r-- 1 mint mint 4 Jan 3 21:33 aaa
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump |
Tags |
/bin/test, /bin/[, shell string compare, string compare |
Thread Tools | |
Display Modes | |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
which shell is better? | ibara | OpenBSD General | 7 | 14th March 2014 03:00 PM |
OpenBSD: Comparing Errata and -Stable | jggimi | Guides | 4 | 6th June 2012 06:28 AM |
ask for a shell script | Simon | Programming | 5 | 27th April 2010 01:07 AM |
Shell Scripting with BSD | chavez243 | Programming | 9 | 3rd December 2008 03:03 AM |
Color shell? | giga | FreeBSD General | 3 | 14th August 2008 12:07 AM |