DaemonForums  

Go Back   DaemonForums > Miscellaneous > Programming

Programming C, bash, Python, Perl, PHP, Java, you name it.

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 21st September 2010
cq04cw cq04cw is offline
New User
 
Join Date: Sep 2010
Posts: 5
Thanked 0 Times in 0 Posts
Unhappy is there difference between two variations of sh command substitution?

PHP Code:
set -x     # open xtrace option to help for debugging
aa=AAAA   # set $aa to AAAA
aa=AAAA
_var=aa    # set $_var to aa
_var=aa
$ echo ${aa}
+ echo 
AAAA
AAAA
$ echo ${_var}
+ echo 
aa
aa
$ echo ${b}
+ echo

b=$( eval echo \$$_var )   # this method as expected
+ eval echo '$aa'
+ echo AAAA
b=AAAA
$ echo ${b}
+ echo 
AAAA
AAAA
b=`eval echo \$$_var`    # this method not as expected ,should it be same result as previous method? 
+ eval echo 1401_var
+ echo 1401_var
b=1401_var
$ echo ${b}
+ echo 
1401_var
1401_var 

ref to "http://www.freebsd.org/cgi/man.cgi?query=sh&manpath=FreeBSD+8.1-RELEASE" command substitution section
environment ===
FreeBSD abc.xyz.com 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Mon Jul 19 02:55:53 UTC 2010 root@almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386
Reply With Quote
  #2   (View Single Post)  
Old 21st September 2010
rocket357's Avatar
rocket357 rocket357 is offline
Real Name: Jonathon
Wannabe OpenBSD porter
 
Join Date: Jun 2010
Location: 127.0.0.1
Posts: 322
Thanked 9 Times in 9 Posts
Default

Quote:
Originally Posted by cq04cw View Post
PHP Code:
b=$( eval echo \$$_var )   # this method as expected
b=`eval echo \$$_var`    # this method not as expected ,should it be same result as previous method? 
On OpenBSD-CURRENT, which exhibits the same behavior:

Quote:
Originally Posted by man ksh
For $(command) substitutions, normal quoting rules are used when command is parsed; however, for the `command` form, a `\' followed by any of `$', ``', or `\' is stripped (a `\' followed by any other character is unchanged).
Simply put, for `command` form substitution, \$ is treated in a special manner and what you get from \$$ is $$, or the pid of the shell you're working in right now.

PHP Code:
$ echo $$
21638
ksh
$ echo $$
12413
$ exit
$ echo $$
21638 
This, however, works:

PHP Code:
b=`eval echo \\$$_var

Last edited by rocket357; 21st September 2010 at 02:27 PM.
Reply With Quote
  #3   (View Single Post)  
Old 23rd September 2010
cq04cw cq04cw is offline
New User
 
Join Date: Sep 2010
Posts: 5
Thanked 0 Times in 0 Posts
Default

Thanks, rocket357.

The first form b=$( eval echo \$$_var ) which i understood is parsed like this:
pass1: eval echo $aa ## \$ is treated as dollar sign $, $_var is aa
pass2: eval it , and assign result (echo $aa 's output) to variable b
is it right to think of it ?

however, the second form b=`eval echo \\$$_var` which i can't read it.
pass1: eval echo \$aa ## \\ -> \ (as manpage explained), $_var -> aa
pass2: eval it ? echo \$aa -> $aa , $aa is output of echo , b=$aa, but the result is b=AAAA ($aa's val).

how to understand the second form ?
Reply With Quote
  #4   (View Single Post)  
Old 23rd September 2010
rocket357's Avatar
rocket357 rocket357 is offline
Real Name: Jonathon
Wannabe OpenBSD porter
 
Join Date: Jun 2010
Location: 127.0.0.1
Posts: 322
Thanked 9 Times in 9 Posts
Default

Quote:
Originally Posted by cq04cw View Post
the second form b=`eval echo \\$$_var` which i can't read it.
pass1: eval echo \$aa ## \\ -> \ (as manpage explained), $_var -> aa
pass2: eval it ? echo \$aa -> $aa , $aa is output of echo , b=$aa, but the result is b=AAAA ($aa's val).

how to understand the second form ?
The manpage states "a `\' followed by any of `$', ``', or `\' is stripped", so the first strip is for \\, leaving \$...but since \$ is in the list, too, the second \ is stripped as well, leaving $$_var, which is $aa, which evals to AAAA.

PHP Code:
set -x
$ `eval echo \\$$`
+ eval echo $$  
# BOTH \'s are stripped!
+ echo 31889
31889
/bin/ksh31889not found 
Reply With Quote
  #5   (View Single Post)  
Old 23rd September 2010
TerryP's Avatar
TerryP TerryP is offline
Arp Constable
 
Join Date: May 2008
Location: USofA
Posts: 1,547
Thanked 112 Times in 104 Posts
Default

In the context of Bourne shell scripting:

For all practical intents and purposes, $(string) is just a synonym for `string`. $() was added as a more explicit way of doing `` around the 80s, so $() is not as portable as ``.

I have not seen any shell that does not support $(), that is not old as petrified dog poo. I personally use `` in scripts because it gains a small bit of portability at no sacrifice in readability over $(). Yes, I'm to lazy to change from ``to $() in case I get stuck in an antique sh.
__________________
My Journal

Thou shalt check the array bounds of all strings (indeed, all arrays), for surely where thou typest ``foo'' someone someday shall type ``supercalifragilisticexpialidocious''.
Reply With Quote
  #6   (View Single Post)  
Old 23rd September 2010
Carpetsmoker's Avatar
Carpetsmoker Carpetsmoker is offline
Real Name: Martin
Old man from scene 24
 
Join Date: Apr 2008
Location: Eindhoven, Netherlands
Posts: 2,069
Thanked 198 Times in 156 Posts
Default

Not sure how this relates to the OP's question (Which I find fairly confusing to be honest), but $() has an advantage in that it's better "nestable", for example consider:

Code:
$(ls | grep $(cat somefile))
There are conditions where `` will fail.

As for portability: $() has long since been a part of the POSIX standard. Writing shell scripts with `` for portability is like modifying your programs for Windows 95.
__________________
UNIX was not designed to stop you from doing stupid things, because that would also stop you from doing clever things.
Reply With Quote
  #7   (View Single Post)  
Old 23rd September 2010
BSDfan666 BSDfan666 is offline
Real Name: N/A, this is the interweb.
Helpful companion
 
Join Date: Apr 2008
Location: Ontario, Canada
Posts: 2,223
Thanked 193 Times in 184 Posts
Default

I also prefer using $() wherever possible, apparently it was introduced with Korn shells and GNU's bash.

As mentioned by Carpetsmoker, this has been merged into POSIX/SUS standards and both are perfectly legal.. and a compliant 'sh' must support both.

http://www.opengroup.org/onlinepubs/...l#tag_18_06_03
Reply With Quote
  #8   (View Single Post)  
Old 24th September 2010
TerryP's Avatar
TerryP TerryP is offline
Arp Constable
 
Join Date: May 2008
Location: USofA
Posts: 1,547
Thanked 112 Times in 104 Posts
Default

CS, you'll just have to excuse those of us who test their scripts against shells who have yet to be certified as passing the standard, and prefer common-dialect portability over requiring the latest and greatest standards without real need of those features. Ditto for any C99 versus C89 debates. I'm a practical man not a theologian.

As to the OP, all I see is issues relating to $(), ``, and escaping, and wouldn't mind if the OP tried a more direct way of phrasing it.
__________________
My Journal

Thou shalt check the array bounds of all strings (indeed, all arrays), for surely where thou typest ``foo'' someone someday shall type ``supercalifragilisticexpialidocious''.
Reply With Quote
  #9   (View Single Post)  
Old 24th September 2010
IdOp's Avatar
IdOp IdOp is offline
Too dumb for a smartphone
 
Join Date: May 2008
Location: twisting on the daemon's fork(2)
Posts: 563
Thanked 14 Times in 13 Posts
Default

I use both $() and `` but seem to be shifting more toward $().

Advantages of `` are that it's easier to type and easier on the eyes, so I don't mind it in a short line such as

% VAR=`command`

but the individual back-quotes tend to get easily lost in longer statements, so there I'll use $() as it's easier to spot.

But I also like consistency so maybe that's why the slide toward $() everywhere.
Reply With Quote
Old 24th September 2010
rocket357's Avatar
rocket357 rocket357 is offline
Real Name: Jonathon
Wannabe OpenBSD porter
 
Join Date: Jun 2010
Location: 127.0.0.1
Posts: 322
Thanked 9 Times in 9 Posts
Default

Quote:
Originally Posted by IdOp View Post
I use both $() and `` but seem to be shifting more toward $().

Advantages of `` are that it's easier to type and easier on the eyes, so I don't mind it in a short line such as

% VAR=`command`

but the individual back-quotes tend to get easily lost in longer statements, so there I'll use $() as it's easier to spot.

But I also like consistency so maybe that's why the slide toward $() everywhere.
My sentiments exactly. It's like you read my mind.
Reply With Quote
Old 24th September 2010
ocicat ocicat is offline
Administrator
 
Join Date: Apr 2008
Posts: 2,888
Thanked 190 Times in 160 Posts
Default

For entertainment, I looked up the standard to see what it says about the difference between backticks & $():

http://www.opengroup.org/onlinepubs/...xcu/chap2.html

So here's the raw meat being thrown into the lions' cage:
Code:
The $() form of command substitution solves a problem of inconsistent behaviour 
when using backquotes. For example:

Command 	Output
echo '\$x' 	\$x
echo `echo '\$x'` 	$x
echo $(echo '\$x') 	\$x

Additionally, the backquoted syntax has historical restrictions on the contents 
of the embedded command. While the new $() form can process any kind of valid 
embedded script, the backquoted form cannot handle some valid scripts that 
include backquotes. For example, these otherwise valid embedded scripts do 
not work in the left column, but do work on the right:


echo `                         echo $(
cat <<\eof                     cat <<\eof
a here-doc with `              a here-doc with )
eof                            eof
`                              )

echo `                         echo $(
echo abc # a comment with `    echo abc # a comment with )
`                              )

echo `                         echo $(
echo '`'                       echo ')'
`                              )

Because of these inconsistent behaviours, the backquoted variety of command 
substitution is not recommended for new applications that nest command substitutions 
or attempt to embed complex scripts.
Reply With Quote
Old 25th September 2010
cq04cw cq04cw is offline
New User
 
Join Date: Sep 2010
Posts: 5
Thanked 0 Times in 0 Posts
Default

Quote:
Originally Posted by rocket357 View Post
The manpage states "a `\' followed by any of `$', ``', or `\' is stripped", so the first strip is for \\, leaving \$...but since \$ is in the list, too, the second \ is stripped as well, leaving $$_var, which is $aa, which evals to AAAA.

PHP Code:
set -x
$ `eval echo \\$$`
+ eval echo $$  
# BOTH \'s are stripped!
+ echo 31889
31889
/bin/ksh31889not found 
yes, it seem a letter clear to me. but if you add more backslash in front of it (see examples below), how you can read it ?

PHP Code:
b=`eval echo \\\$$_var# ex1
+ eval echo '$aa'
+ echo AAAA
b=AAAA
b=`eval echo \\\\$$_var# ex2
+ eval echo '\1018_var'
+ echo 1018_var
b=1018_var 
ex1:
The interpreter read in command line, and first two backslash is treated as \ literally, and \$ is treated as $ literally, $_var is replaced by $_var's value, "aa"
after first interpreted, the interpreter also find it there's \$ because of result of first read, and \$ is treated as $ literally ,
is it right ot understand it ?

ex2:
the interpreter read in , and first two backslash is treated \ literally , and following two backslash is also, and following two dollar sign is replaced by current pid value.
after first read(the first four backslash is interpreted \\), then this \\ is also interpreted \.

if ex1 and ex2 do make sense.
look at another example
PHP Code:
b=`eval echo \\\\\\$$_var# ex3
+ eval echo '\$aa'
+ echo '$aa'
b='$aa' 
ex3:
the interpreter read in command, the first two backslash is \, the second pair is also \, the third pair is also \, and the following two dollar sign is shell pid
after first read, the text is look like this: \\\1018_var, however, as you can see, the result is not expand $$ to pid, i think it interpret byte by byte, instead of read a line whole, like this: the first three pair backslash is interpreted three literal \, then \\\$$_var(assume it read byte by byte ) is interpreted as first two backslash is \ , third backslash and fourth dollar sign is literal $, and result of this is \$aa.

question 1: how the interpreter interpret command line , line by line or byte by byte, or otherwise?
question 2: why the \$ sequence not be interpreted, it's also in the list `$', ``', or `\'?
Reply With Quote
Reply

Thread Tools
Display Modes

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 On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Striking difference between the Linux community and BSD windependence Off-Topic 79 6th December 2010 02:04 AM
What's the difference between these two memory modules? Carpetsmoker General Hardware 2 25th November 2008 03:13 PM
difference between jdk16 and diablo 1.6 cuongvt FreeBSD Ports and Packages 8 16th October 2008 12:17 AM
difference between rc.conf and loader.conf disappearedng FreeBSD General 5 3rd September 2008 05:54 AM
Difference between chpass and pw disappearedng FreeBSD General 9 7th July 2008 11:12 PM


All times are GMT. The time now is 06:41 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick