Latest LQ Deal: Linux Power User Bundle
Go Back > Forums > Linux Forums > Linux - Newbie
User Name
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!


  Search this Thread
Old 04-02-2013, 09:32 AM   #1
LQ Newbie
Registered: Apr 2013
Posts: 2

Rep: Reputation: Disabled
question about command substitution and if statements

Hi guys,
I've been reading various websites about bash, and I still can't figure out why this simple command is causing errors.

I know it's something to do with incorrect expansion, but I can't see what the problem is:

so basically I have an "if" statement in a script;

if [ $( expr ${NPROC} % 16) -eq 0 ]

and this is giving an error:
[12: command not found

where 12 is the correct value of `expr ${NPROC} % 16`

Now I've spent a while fannying around with trying quotes in various combinations (both around the comparison target and the command), and trying different expansions like arithmetic etc and it still isn't working. I realise it should be easy.

Any help regarding figuring out the correct way to do the command substitution would be very welcome, I'd rather learn how to fix this broken expression than an alternative method.

Hope to hear back, cheers guys and girls



ok wow, I didn't realise if conditions needed a space at either side of the content (i.e. [ condition ])
I didn't have that in before, seems I needed it.
Thanks anyway
Feel free to delete this post Mod

Last edited by mrb3nnio; 04-02-2013 at 09:42 AM. Reason: solved myself
Old 04-02-2013, 09:50 AM   #2
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 840

Rep: Reputation: 380Reputation: 380Reputation: 380Reputation: 380
Make sure there's a space between the brackets and whatever is inside them. The [ bracket is not really an operator, but an actual command (usually /usr/bin/[ or a shell builtin, a synonym to test, so it needs to be separated from other tokens by spaces so that the command may be parsed by bash correctly. The closing ] bracket is actually an argument to [, for the sake of intuitivity and readability of the code.


if [ 12 -eq 16 ]
is correct,
if [12 -eq 16]
is not.

That said, instead of expr and [ ], I would recommend to use the bash feature [[ ]], which actually is an operator, and in the case of arithmetical expressions, such as this, the (( )) construct. So,

if (( NPROC % 16 == 0 )); then ...

((NPROC % 16 == 0)) && ...
or even

((NPROC % 16)) || ...
1 members found this post helpful.
Old 04-02-2013, 09:57 AM   #3
LQ Newbie
Registered: Apr 2013
Posts: 2

Original Poster
Rep: Reputation: Disabled
That's interesting about "[" being a command, thanks for the help buddy!
Old 04-02-2013, 11:35 AM   #4
David the H.
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958Reputation: 1958
Please use ***[code][/code]*** tags around your code and data, to preserve the original formatting and to improve readability. Do not use quote tags, bolding, colors, "start/end" lines, or other creative techniques.

Another aspect of "[" being a command is that it's very strict about the number and type of arguments that follow it. A two-value comparison must have exactly four arguments following it, valueA, comparator, valueB, end-bracket. If you're using a variable or something that expands into more values than that, or less, you're going to have trouble:

Bash Pitfall #4, among others.

So remember to always quote your arguments.

That's why, as millgates said, when using advanced shells like bash or ksh it's recommended to use [[..]] for string/file tests, and ((..)) for numerical tests. Avoid using the old [..] test unless you specifically need POSIX-style portability.

Being built-in keywords, rather than separate commands, they can parse their arguments more intelligently, and so have fewer limitations than the old test.

Now for one more thing. As the BashGuide says, "expr is a relic of ancient Rome. Do not wield it.". There is nothing that expr does that cannot be more efficiently done with modern shell built-ins. Unless you're using a truly ancient shell, put it away and forget about it.

In fact, AFAICT, there's only thing expr does that bash can't do directly, and that's return the index number of a character in a string. But even that can be worked around very easily with a couple of simple parameter substitutions.
$ string=foobarbazbumfoobarbazbum
$ expr index "$string" b
$ n="${string%%b*}_" ; echo "${#n}"
In fact, it's even more flexible, because you can also get the index of the last occurrence the same way, as well as other things like the beginning of longer strings:

$ n="${string%b*}_" ; echo "${#n}"
$ n="${string%%baz*}_" ; echo "${#n}"
$ n="${string%baz*}_" ; echo "${#n}"


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
Bash - command substitution kopert Programming 8 09-18-2012 04:13 AM
quick question on order of operation with command substitution dsollen Linux - Newbie 3 09-15-2009 08:04 AM
Command substitution and sed daYz Linux - General 9 11-04-2006 01:15 AM
command substitution: ^ rhxk Linux - General 2 04-06-2006 09:51 AM
if statements and case statements not working in bourne shell script mparkhurs Programming 3 06-12-2004 02:41 AM

All times are GMT -5. The time now is 07:24 PM.

Main Menu
Write for LQ is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration