REOPEN: Perform arithmetic expansion inside parameter expansion? [duplicate]

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
-2
down vote

favorite













This question already has an answer here:



  • Double and triple substitution in bash and zsh

    5 answers



Please reopen. This is not a duplicate, because here I am asking why it doesn't work, not just for workaround.




Bash manual says that




tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)




If I understand http://unix.stackexchange.com/a/270324/674 correctly, "left-to-right" means that "brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution" have the same priority.



So is it possible to use arithmetic expansion inside parameter expansion? (i.e. one level recursion)



If no, why can't arithmetic expansion work inside parameter expansion, given that "tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)"?



If yes, how?



For example,



$ set hello world
$ echo $2
world
$ echo $$((1+1))
bash: $$((1+1)): bad substitution


I hope to



  • first expand $((1+1)) in $$((1+1)) to 2. and

  • then $2 to world.

Thanks.










share|improve this question















marked as duplicate by αғsнιη, Stephen Rauch, Satō Katsura, Kusalananda bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Sep 27 '17 at 6:53


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.










  • 2




    Because that's not left-to-right. What you're hoping for is not left-to-right. The documentation says expansion is done left-to-right. You want something else, I don't know what to call it; maybe "from-inside-to-outside" parsing? Please read the documentation and clear the English words in it like "left-to-right" so you can answer your own questions. (This question contains its own answer.)
    – Wildcard
    Sep 27 '17 at 0:40










  • What the manual tries to say is: parameter expansion is done before arithmetic expansion, so it works the other way around: set 6 7; echo $(($1*$2)) will work as expected.
    – Philippos
    Sep 27 '17 at 6:53






  • 3




    The whole sentence of your citation is: "The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.
    – Philippos
    Sep 27 '17 at 10:44






  • 3




    @Tim they don't (and can't) have the same priority. Parameter expansion is done before arithmetic expansion, so $(( 1 + $a:-5 )) will work but $ $((1 + 1)) won't. To solve your requirement you would need set 4 5; b=$((1+1)); echo $!b
    – roaima
    Sep 27 '17 at 12:14







  • 1




    Just to add more confusion in Tim's head, $@:$((1+1)):1 would work though ;-) Hint: $@:1+1:1 would work too.
    – xhienne
    Sep 27 '17 at 12:51














up vote
-2
down vote

favorite













This question already has an answer here:



  • Double and triple substitution in bash and zsh

    5 answers



Please reopen. This is not a duplicate, because here I am asking why it doesn't work, not just for workaround.




Bash manual says that




tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)




If I understand http://unix.stackexchange.com/a/270324/674 correctly, "left-to-right" means that "brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution" have the same priority.



So is it possible to use arithmetic expansion inside parameter expansion? (i.e. one level recursion)



If no, why can't arithmetic expansion work inside parameter expansion, given that "tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)"?



If yes, how?



For example,



$ set hello world
$ echo $2
world
$ echo $$((1+1))
bash: $$((1+1)): bad substitution


I hope to



  • first expand $((1+1)) in $$((1+1)) to 2. and

  • then $2 to world.

Thanks.










share|improve this question















marked as duplicate by αғsнιη, Stephen Rauch, Satō Katsura, Kusalananda bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Sep 27 '17 at 6:53


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.










  • 2




    Because that's not left-to-right. What you're hoping for is not left-to-right. The documentation says expansion is done left-to-right. You want something else, I don't know what to call it; maybe "from-inside-to-outside" parsing? Please read the documentation and clear the English words in it like "left-to-right" so you can answer your own questions. (This question contains its own answer.)
    – Wildcard
    Sep 27 '17 at 0:40










  • What the manual tries to say is: parameter expansion is done before arithmetic expansion, so it works the other way around: set 6 7; echo $(($1*$2)) will work as expected.
    – Philippos
    Sep 27 '17 at 6:53






  • 3




    The whole sentence of your citation is: "The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.
    – Philippos
    Sep 27 '17 at 10:44






  • 3




    @Tim they don't (and can't) have the same priority. Parameter expansion is done before arithmetic expansion, so $(( 1 + $a:-5 )) will work but $ $((1 + 1)) won't. To solve your requirement you would need set 4 5; b=$((1+1)); echo $!b
    – roaima
    Sep 27 '17 at 12:14







  • 1




    Just to add more confusion in Tim's head, $@:$((1+1)):1 would work though ;-) Hint: $@:1+1:1 would work too.
    – xhienne
    Sep 27 '17 at 12:51












up vote
-2
down vote

favorite









up vote
-2
down vote

favorite












This question already has an answer here:



  • Double and triple substitution in bash and zsh

    5 answers



Please reopen. This is not a duplicate, because here I am asking why it doesn't work, not just for workaround.




Bash manual says that




tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)




If I understand http://unix.stackexchange.com/a/270324/674 correctly, "left-to-right" means that "brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution" have the same priority.



So is it possible to use arithmetic expansion inside parameter expansion? (i.e. one level recursion)



If no, why can't arithmetic expansion work inside parameter expansion, given that "tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)"?



If yes, how?



For example,



$ set hello world
$ echo $2
world
$ echo $$((1+1))
bash: $$((1+1)): bad substitution


I hope to



  • first expand $((1+1)) in $$((1+1)) to 2. and

  • then $2 to world.

Thanks.










share|improve this question
















This question already has an answer here:



  • Double and triple substitution in bash and zsh

    5 answers



Please reopen. This is not a duplicate, because here I am asking why it doesn't work, not just for workaround.




Bash manual says that




tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)




If I understand http://unix.stackexchange.com/a/270324/674 correctly, "left-to-right" means that "brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution" have the same priority.



So is it possible to use arithmetic expansion inside parameter expansion? (i.e. one level recursion)



If no, why can't arithmetic expansion work inside parameter expansion, given that "tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)"?



If yes, how?



For example,



$ set hello world
$ echo $2
world
$ echo $$((1+1))
bash: $$((1+1)): bad substitution


I hope to



  • first expand $((1+1)) in $$((1+1)) to 2. and

  • then $2 to world.

Thanks.





This question already has an answer here:



  • Double and triple substitution in bash and zsh

    5 answers







bash






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Sep 27 '17 at 12:20

























asked Sep 26 '17 at 23:12









Tim

23k66225408




23k66225408




marked as duplicate by αғsнιη, Stephen Rauch, Satō Katsura, Kusalananda bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Sep 27 '17 at 6:53


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.






marked as duplicate by αғsнιη, Stephen Rauch, Satō Katsura, Kusalananda bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Sep 27 '17 at 6:53


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









  • 2




    Because that's not left-to-right. What you're hoping for is not left-to-right. The documentation says expansion is done left-to-right. You want something else, I don't know what to call it; maybe "from-inside-to-outside" parsing? Please read the documentation and clear the English words in it like "left-to-right" so you can answer your own questions. (This question contains its own answer.)
    – Wildcard
    Sep 27 '17 at 0:40










  • What the manual tries to say is: parameter expansion is done before arithmetic expansion, so it works the other way around: set 6 7; echo $(($1*$2)) will work as expected.
    – Philippos
    Sep 27 '17 at 6:53






  • 3




    The whole sentence of your citation is: "The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.
    – Philippos
    Sep 27 '17 at 10:44






  • 3




    @Tim they don't (and can't) have the same priority. Parameter expansion is done before arithmetic expansion, so $(( 1 + $a:-5 )) will work but $ $((1 + 1)) won't. To solve your requirement you would need set 4 5; b=$((1+1)); echo $!b
    – roaima
    Sep 27 '17 at 12:14







  • 1




    Just to add more confusion in Tim's head, $@:$((1+1)):1 would work though ;-) Hint: $@:1+1:1 would work too.
    – xhienne
    Sep 27 '17 at 12:51












  • 2




    Because that's not left-to-right. What you're hoping for is not left-to-right. The documentation says expansion is done left-to-right. You want something else, I don't know what to call it; maybe "from-inside-to-outside" parsing? Please read the documentation and clear the English words in it like "left-to-right" so you can answer your own questions. (This question contains its own answer.)
    – Wildcard
    Sep 27 '17 at 0:40










  • What the manual tries to say is: parameter expansion is done before arithmetic expansion, so it works the other way around: set 6 7; echo $(($1*$2)) will work as expected.
    – Philippos
    Sep 27 '17 at 6:53






  • 3




    The whole sentence of your citation is: "The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.
    – Philippos
    Sep 27 '17 at 10:44






  • 3




    @Tim they don't (and can't) have the same priority. Parameter expansion is done before arithmetic expansion, so $(( 1 + $a:-5 )) will work but $ $((1 + 1)) won't. To solve your requirement you would need set 4 5; b=$((1+1)); echo $!b
    – roaima
    Sep 27 '17 at 12:14







  • 1




    Just to add more confusion in Tim's head, $@:$((1+1)):1 would work though ;-) Hint: $@:1+1:1 would work too.
    – xhienne
    Sep 27 '17 at 12:51







2




2




Because that's not left-to-right. What you're hoping for is not left-to-right. The documentation says expansion is done left-to-right. You want something else, I don't know what to call it; maybe "from-inside-to-outside" parsing? Please read the documentation and clear the English words in it like "left-to-right" so you can answer your own questions. (This question contains its own answer.)
– Wildcard
Sep 27 '17 at 0:40




Because that's not left-to-right. What you're hoping for is not left-to-right. The documentation says expansion is done left-to-right. You want something else, I don't know what to call it; maybe "from-inside-to-outside" parsing? Please read the documentation and clear the English words in it like "left-to-right" so you can answer your own questions. (This question contains its own answer.)
– Wildcard
Sep 27 '17 at 0:40












What the manual tries to say is: parameter expansion is done before arithmetic expansion, so it works the other way around: set 6 7; echo $(($1*$2)) will work as expected.
– Philippos
Sep 27 '17 at 6:53




What the manual tries to say is: parameter expansion is done before arithmetic expansion, so it works the other way around: set 6 7; echo $(($1*$2)) will work as expected.
– Philippos
Sep 27 '17 at 6:53




3




3




The whole sentence of your citation is: "The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.
– Philippos
Sep 27 '17 at 10:44




The whole sentence of your citation is: "The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.
– Philippos
Sep 27 '17 at 10:44




3




3




@Tim they don't (and can't) have the same priority. Parameter expansion is done before arithmetic expansion, so $(( 1 + $a:-5 )) will work but $ $((1 + 1)) won't. To solve your requirement you would need set 4 5; b=$((1+1)); echo $!b
– roaima
Sep 27 '17 at 12:14





@Tim they don't (and can't) have the same priority. Parameter expansion is done before arithmetic expansion, so $(( 1 + $a:-5 )) will work but $ $((1 + 1)) won't. To solve your requirement you would need set 4 5; b=$((1+1)); echo $!b
– roaima
Sep 27 '17 at 12:14





1




1




Just to add more confusion in Tim's head, $@:$((1+1)):1 would work though ;-) Hint: $@:1+1:1 would work too.
– xhienne
Sep 27 '17 at 12:51




Just to add more confusion in Tim's head, $@:$((1+1)):1 would work though ;-) Hint: $@:1+1:1 would work too.
– xhienne
Sep 27 '17 at 12:51










1 Answer
1






active

oldest

votes

















up vote
3
down vote













You need either eval or indirection for this:



eval echo $$((1+1))
index=$((1+1))
echo $!index





share|improve this answer




















  • Thanks. I understand the two ways you mentioned. Why can't arithmetic expansion work inside parameter expansion, given that "tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)"?
    – Tim
    Sep 26 '17 at 23:42






  • 2




    @Tim, because that wouldn't be left-to-right.
    – Wildcard
    Sep 27 '17 at 0:37

















1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
3
down vote













You need either eval or indirection for this:



eval echo $$((1+1))
index=$((1+1))
echo $!index





share|improve this answer




















  • Thanks. I understand the two ways you mentioned. Why can't arithmetic expansion work inside parameter expansion, given that "tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)"?
    – Tim
    Sep 26 '17 at 23:42






  • 2




    @Tim, because that wouldn't be left-to-right.
    – Wildcard
    Sep 27 '17 at 0:37














up vote
3
down vote













You need either eval or indirection for this:



eval echo $$((1+1))
index=$((1+1))
echo $!index





share|improve this answer




















  • Thanks. I understand the two ways you mentioned. Why can't arithmetic expansion work inside parameter expansion, given that "tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)"?
    – Tim
    Sep 26 '17 at 23:42






  • 2




    @Tim, because that wouldn't be left-to-right.
    – Wildcard
    Sep 27 '17 at 0:37












up vote
3
down vote










up vote
3
down vote









You need either eval or indirection for this:



eval echo $$((1+1))
index=$((1+1))
echo $!index





share|improve this answer












You need either eval or indirection for this:



eval echo $$((1+1))
index=$((1+1))
echo $!index






share|improve this answer












share|improve this answer



share|improve this answer










answered Sep 26 '17 at 23:25









Hauke Laging

53.7k1282130




53.7k1282130











  • Thanks. I understand the two ways you mentioned. Why can't arithmetic expansion work inside parameter expansion, given that "tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)"?
    – Tim
    Sep 26 '17 at 23:42






  • 2




    @Tim, because that wouldn't be left-to-right.
    – Wildcard
    Sep 27 '17 at 0:37
















  • Thanks. I understand the two ways you mentioned. Why can't arithmetic expansion work inside parameter expansion, given that "tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)"?
    – Tim
    Sep 26 '17 at 23:42






  • 2




    @Tim, because that wouldn't be left-to-right.
    – Wildcard
    Sep 27 '17 at 0:37















Thanks. I understand the two ways you mentioned. Why can't arithmetic expansion work inside parameter expansion, given that "tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)"?
– Tim
Sep 26 '17 at 23:42




Thanks. I understand the two ways you mentioned. Why can't arithmetic expansion work inside parameter expansion, given that "tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion)"?
– Tim
Sep 26 '17 at 23:42




2




2




@Tim, because that wouldn't be left-to-right.
– Wildcard
Sep 27 '17 at 0:37




@Tim, because that wouldn't be left-to-right.
– Wildcard
Sep 27 '17 at 0:37


Popular posts from this blog

Peggy Mitchell

Palaiologos

The Forum (Inglewood, California)