A $(( expression )) bug?


 
Thread Tools Search this Thread
Top Forums UNIX for Advanced & Expert Users A $(( expression )) bug?
# 15  
Old 10-02-2016
Quote:
Originally Posted by MadeInGermany
Just had a first look at shellcheck.
It looks like it makes suggestions in addition to the real faults that are found by sh -nx
Well here is the code that shellcheck checked:-
Code:
Last login: Sun Oct  2 11:18:10 on ttys000
AMIGA:barrywalker~> cd Desktop/Code/Shell
AMIGA:barrywalker~/Desktop/Code/Shell> cat BUG1.sh
#!/bin/sh
txt="12345"
echo "$(( # == txt ))"
echo "$(( $# == txt ))"
echo "$(( $# == $txt ))"
echo "$(( # == $txt ))"
echo "$(( # = txt ))"
echo "$(( $# = txt ))"
echo "$(( $# = $txt ))"
echo "$(( # = $txt ))"
AMIGA:barrywalker~/Desktop/Code/Shell> sh -n BUG1.sh
AMIGA:barrywalker~/Desktop/Code/Shell> bash -n BUG1.sh
AMIGA:barrywalker~/Desktop/Code/Shell> _

And I decided to [ba]sh -n BUG1.sh and it says it is syntactically correct.
Again /Me shrugs...
Have I discovered a general SHELL bug, although esoteric is STILL a bug?
Are these arithmetic related ERRORs capable of being hacked from the outside?
(I have no idea as I am a mere amateur.)
Why in fact does bash -n NOT pick it up on at least my OSX 10.11.6 version of 'bash'?
# 16  
Old 10-03-2016
Static checking

Hi.

The definition for the syntax check is:
Code:
              -n      Read commands but do not execute them.  This may be used
                      to  check  a  shell  script  for syntax errors.

Here is how I see this.

If no code is executed, then variables are not defined. If there is no execution, then commands like [ are not executed, and there can be no check for the internal syntax of expressions after [ -- which is the same as command test.

I think the syntax check of the -n option can only check structural syntax. Below are some examples that I thought of, and there are probably more.

So to debug a code, I think a preliminary run with bash -n can be used to help eliminate gross errors in structure, missing elements like then or do, unmatched parens and quotes, etc. Then the script can be run to get rid of the internal syntax errors, like those mentioned above with test and friends, and finally shellcheck to look at other items.

So check, run, check would be how I would approach this if I were to write long sections of code (my longest shell script is just under 800 lines, but most are far smaller). There might be instances where check, check, run might be more useful. It depends on the code and coder.

Best wishes ... cheers, drl

Here are some samples that bash -n can catch as noted by script run-all:
Code:
#!/bin/bash

echo
echo " File contents:"
head -20 se-*

echo
echo " Results of syntax check, noexec:"
for script in se-*
do
  echo
  echo " Results for $script:"
  bash -n $script
done

exit 0

producing:
Code:
$ ./run-all 

 File contents:
==> se-1 <==
#!/bin/bash

if [ something ]
then
  :
else
  :
fi

if [ other ]
  :
else
  :
fi

==> se-2 <==
#!/bin/bash

echo "$(( 0 == 1 ))"

echo "$(( 0 == 1)"

==> se-3 <==
#!/bin/bash

for xxx
do
  :
done

for yyy
do
  :
else
done

==> se-4 <==
#!/bin/bash

echo 1 | cat

| echo 2

==> se-5 <==
#!/bin/bash

echo 1 | cat

& echo 2

==> se-6 <==
#!/bin/bash

[ 0 ] && echo hi

[ 1 ] || echo lo

[ 0 ] &&

==> se-7 <==
#!/bin/bash

echo {1..10}

a() { echo hi; }

b() { echo lo } # omitted semi-colon before }

 Results of syntax check, noexec:

 Results for se-1:
se-1: line 12: syntax error near unexpected token `else'
se-1: line 12: `else'

 Results for se-2:
se-2: line 5: unexpected EOF while looking for matching `"'
se-2: line 6: syntax error: unexpected end of file

 Results for se-3:
se-3: line 11: syntax error near unexpected token `else'
se-3: line 11: `else'

 Results for se-4:
se-4: line 5: syntax error near unexpected token `|'
se-4: line 5: `| echo 2'

 Results for se-5:
se-5: line 5: syntax error near unexpected token `&'
se-5: line 5: `& echo 2'

 Results for se-6:
se-6: line 8: syntax error: unexpected end of file

 Results for se-7:
se-7: line 8: syntax error: unexpected end of file

# 17  
Old 10-03-2016
Hi drl...
How about this then:-
$[ ( expression ) ] is runtime identical to $(( expression )) , yes...
If the error reports are different then does that imply that they might not be runtime identical?
If not then explain why some of these errors are different?
These old arithmetic expressions were what brought about this thread in the first place.
Code:
Last login: Mon Oct  3 14:53:41 on console
AMIGA:barrywalker~> txt="12345"
AMIGA:barrywalker~> echo "$(( # = txt ))"
-bash: bad substitution: no closing `)' in "$(( # = txt ))"
AMIGA:barrywalker~> echo "$[ ( # = txt ) ]"
-bash: ( # = txt ) : syntax error: operand expected (error token is "# = txt ) ")
AMIGA:barrywalker~> echo "$(( # = $txt ))"
-bash: bad substitution: no closing `)' in "$(( # = $txt ))"
AMIGA:barrywalker~> echo "$[ ( # = $txt ) ]"
-bash: ( # = 12345 ) : syntax error: operand expected (error token is "# = 12345 ) ")
AMIGA:barrywalker~> echo "$(( $# = $txt ))"
-bash: 0 = 12345 : attempted assignment to non-variable (error token is "= 12345 ")
AMIGA:barrywalker~> echo "$[ ( $# = $txt ) ]"
-bash: ( 0 = 12345 ) : attempted assignment to non-variable (error token is "= 12345 ) ")
AMIGA:barrywalker~> echo "$(( $# = txt ))"
-bash: 0 = txt : attempted assignment to non-variable (error token is "= txt ")
AMIGA:barrywalker~> echo "$[ ( $# = txt ) ]"
-bash: ( 0 = txt ) : attempted assignment to non-variable (error token is "= txt ) ")
AMIGA:barrywalker~> bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
Copyright (C) 2007 Free Software Foundation, Inc.
AMIGA:barrywalker~> _

At this pont I am going to bow out gracefully and keep a watchful eye on this thread.
# 18  
Old 10-03-2016
Hi, Barry.

On a system like:
Code:
OS, ker|rel, machine: Apple/BSD, Darwin 9.8.0, Power Macintosh
Distribution        : Mac OS X 10.5.8 (leopard, workstation)
bash GNU bash 3.2.17

there is no mention of $[ in the man page. There might be in your version 57.

Interactive results there:
Code:
$ echo "$(( # = txt ))"
-bash: bad substitution: no closing `)' in "$(( # = txt ))"
$ echo "$[ ( # = txt ) ]"
-bash: ( # = txt ) : syntax error: operand expected (error token is "# = txt ) ")

The man page for a modern bash 4.3.30 notes:
Code:
       The  old  format  $[expression]  is  deprecated  and will be removed in
       upcoming versions of bash.

The man page for modern dash 0.5.7-4+b1 does not mention $[ at all.

For this code:
Code:
#!/bin/bash

# The  old  format  $[expression]  is  deprecated  and will be removed in
# upcoming versions of bash.
# -- man bash

x=12345

echo "$(( x == txt ))"

echo "$[ x == txt ]"

echo "$[ x == 12345 ]"

echo "$[ ( # = txt ) ]"

Both dash -n and bash -n return nothing on that file.

Executing the code first with bash on that file produces:
Code:
$ bash se-8
0
0
1
se-8: line 15: ( # = txt ) : syntax error: operand expected (error token is "# = txt ) ")

then dash:
Code:
$ dash se-8
0
$[ x == txt ]
$[ x == 12345 ]
$[ ( # = txt ) ]

So my conclusion is that $[ is not portable, it is not equivalent to $((, and it will be removed from future versions of bash, as has been done with dash currently.

Judging from the output comparing $(( to $[, I would say that they have either: a) differing syntax requirements, or b) old code for $[ was not updated. I tend to think the former.

So I would say, in addition to my suggested sequence in a previous post for bashcheck / bashrun / shellcheck, I would advise changing $[ to $((

If you are writing to the lowest common denominator, say sh (which may link to dash as it does in Debian), then you might want look at script checkbashisms to identify bash-only constructs.

Quote:
Originally Posted by wisecracker
At this pont I am going to bow out gracefully and keep a watchful eye on this thread.
Yeah, me too Smilie

Best wishes ... cheers, drl

Last edited by drl; 10-04-2016 at 10:38 AM.. Reason: Correct minor typos.
Login or Register to Ask a Question

Previous Thread | Next Thread

8 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Why Relational Expression is Writing to a Expression?

Hello All, Not sure why this is happening... When the following If Statement is evaluated for some reason it is creating a file in the CWD called '0'. I've seen this happen before, just not in an If Statement... CODE: if then DIR_NAME="$1" DIR_SIZE=0 STATUS="" else... (3 Replies)
Discussion started by: mrm5102
3 Replies

2. UNIX for Advanced & Expert Users

sed: -e expression #1, char 0: no previous regular expression

Hello All, I'm trying to extract the lines between two consecutive elements of an array from a file. My array looks like: problem_arr=(PRS111 PRS213 PRS234) j=0 while } ] do k=`expr $j + 1` sed -n "/${problem_arr}/,/${problem_arr}/p" problemid.txt ---some operation goes... (11 Replies)
Discussion started by: InduInduIndu
11 Replies

3. Programming

Perl: How to read from a file, do regular expression and then replace the found regular expression

Hi all, How am I read a file, find the match regular expression and overwrite to the same files. open DESTINATION_FILE, "<tmptravl.dat" or die "tmptravl.dat"; open NEW_DESTINATION_FILE, ">new_tmptravl.dat" or die "new_tmptravl.dat"; while (<DESTINATION_FILE>) { # print... (1 Reply)
Discussion started by: jessy83
1 Replies

4. Shell Programming and Scripting

Integer expression expected: with regular expression

CA_RELEASE has a value of 6. I need to check if that this is a numeric value. if not error. source $CA_VERSION_DATA if * ] then echo "CA_RELESE $CA_RELEASE is invalid" exit -1 fi + source /etc/ncgl/ca_version_data ++ CA_PRODUCT_ID=samxts ++ CA_RELEASE=6 ++ CA_WEEK_NO=7 ++... (3 Replies)
Discussion started by: ketkee1985
3 Replies

5. UNIX for Dummies Questions & Answers

where's the bug?

#!/bin/bash if then #echo "infinite loop" exit 0 fi when I run this file I get the following error: ./test_infinite_loop: line 5: syntax error near unexpected token `fi' ./test_infinite_loop: line 5: `fi' :confused: (4 Replies)
Discussion started by: jon80
4 Replies

6. AIX

bug in 43 ???

xxxxserver# lsattr -El inet0 | grep 255.240.0.0,32.224.0.0,32.78.120.254 | grep '.40' route net,-hopcount,1,-netmask,255.240.0.0,32.224.0.0,32.78.120.254 How this is possible? (1 Reply)
Discussion started by: itik
1 Replies

7. Programming

error: initializer expression list treated as compound expression

I had seen this error for the first time ..... error: initializer expression list treated as compound expression please help.... (12 Replies)
Discussion started by: arunchaudhary19
12 Replies

8. Shell Programming and Scripting

Regular Expression + Aritmetical Expression

Is it possible to combine a regular expression with a aritmetical expression? For example, taking a 8-numbers caracter sequece and casting each output of a grep, comparing to a constant. THX! (2 Replies)
Discussion started by: Z0mby
2 Replies
Login or Register to Ask a Question