How many levels of indirection can I apply in Bash?
Clash Royale CLAN TAG#URR8PPP
up vote
2
down vote
favorite
In bash, I understand we can have variable indirect expansion via two ways:
- Using
declare
:declare -n foo=bar
- Using the
$!..
expansion.
We can combine both:
declare -n foo=SHELL
bar=foo
echo $!bar
gives:
/bin/bash
Is it possible to extend this to more levels?
It's mostly as for writing obfuscated code - some of my friends are challenging each other.
bash indirection
New contributor
add a comment |
up vote
2
down vote
favorite
In bash, I understand we can have variable indirect expansion via two ways:
- Using
declare
:declare -n foo=bar
- Using the
$!..
expansion.
We can combine both:
declare -n foo=SHELL
bar=foo
echo $!bar
gives:
/bin/bash
Is it possible to extend this to more levels?
It's mostly as for writing obfuscated code - some of my friends are challenging each other.
bash indirection
New contributor
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
In bash, I understand we can have variable indirect expansion via two ways:
- Using
declare
:declare -n foo=bar
- Using the
$!..
expansion.
We can combine both:
declare -n foo=SHELL
bar=foo
echo $!bar
gives:
/bin/bash
Is it possible to extend this to more levels?
It's mostly as for writing obfuscated code - some of my friends are challenging each other.
bash indirection
New contributor
In bash, I understand we can have variable indirect expansion via two ways:
- Using
declare
:declare -n foo=bar
- Using the
$!..
expansion.
We can combine both:
declare -n foo=SHELL
bar=foo
echo $!bar
gives:
/bin/bash
Is it possible to extend this to more levels?
It's mostly as for writing obfuscated code - some of my friends are challenging each other.
bash indirection
bash indirection
New contributor
New contributor
New contributor
asked Nov 21 at 13:30
avidenat
1
1
New contributor
New contributor
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
0
down vote
Actually, there is a further method to do indirections in Bash, at least effectively: If you have a=1
and b=a
, you can get the value of a
through b
like so:
eval echo $$b
This can be nested several times:
$ a=1; b=a; c=b; d=c
$ eval eval eval echo \\\$\$$$d
1
Here are the rules to find the right number of backslashes on each level:
- On the innermost level, no backslashes are used.
- On any other level, use 2 n + 1 backslashes, where n is the number of backslashes that are used on the next inner level.
Rationale: Rule 1 is trivial. Rule 2 comes from the fact that you have to apply one backslash more that in the next inner level while you have to escape all those that are not consumed in the current level, i.e. all but one.
As a consequence, the number of needed backslashes diverges exponentially with increasing number of levels so that nesting reaches its limit rather soon for this method.
But one has to emphasize here that this limit is of rather academic nature. In practice, where one has to respect needs such like maintainability, one typically does not want to handle more than two or three levels of indirection in one single expression—no matter which method of indirection is used.
Instead, one can resolve higher levels of indirection by using a loop to iterate something like
value=$variable
variable=$!value
a number of times that is suitable for the given application.
add a comment |
up vote
0
down vote
There is a (large) indirection allowed directly in arithmetic expansion for only numbers.
$ a=123 b=a c=b d=c e=d ; echo $((e))
123
you could expand it with declare:
$ jj=123; for ii in a..fa..z; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
123
But it is not infinite:
$ jj=123; for ii in a..za..z; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
bash: tz: expression recursion level exceeded (error token is "tz")
Is that enough?
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Actually, there is a further method to do indirections in Bash, at least effectively: If you have a=1
and b=a
, you can get the value of a
through b
like so:
eval echo $$b
This can be nested several times:
$ a=1; b=a; c=b; d=c
$ eval eval eval echo \\\$\$$$d
1
Here are the rules to find the right number of backslashes on each level:
- On the innermost level, no backslashes are used.
- On any other level, use 2 n + 1 backslashes, where n is the number of backslashes that are used on the next inner level.
Rationale: Rule 1 is trivial. Rule 2 comes from the fact that you have to apply one backslash more that in the next inner level while you have to escape all those that are not consumed in the current level, i.e. all but one.
As a consequence, the number of needed backslashes diverges exponentially with increasing number of levels so that nesting reaches its limit rather soon for this method.
But one has to emphasize here that this limit is of rather academic nature. In practice, where one has to respect needs such like maintainability, one typically does not want to handle more than two or three levels of indirection in one single expression—no matter which method of indirection is used.
Instead, one can resolve higher levels of indirection by using a loop to iterate something like
value=$variable
variable=$!value
a number of times that is suitable for the given application.
add a comment |
up vote
0
down vote
Actually, there is a further method to do indirections in Bash, at least effectively: If you have a=1
and b=a
, you can get the value of a
through b
like so:
eval echo $$b
This can be nested several times:
$ a=1; b=a; c=b; d=c
$ eval eval eval echo \\\$\$$$d
1
Here are the rules to find the right number of backslashes on each level:
- On the innermost level, no backslashes are used.
- On any other level, use 2 n + 1 backslashes, where n is the number of backslashes that are used on the next inner level.
Rationale: Rule 1 is trivial. Rule 2 comes from the fact that you have to apply one backslash more that in the next inner level while you have to escape all those that are not consumed in the current level, i.e. all but one.
As a consequence, the number of needed backslashes diverges exponentially with increasing number of levels so that nesting reaches its limit rather soon for this method.
But one has to emphasize here that this limit is of rather academic nature. In practice, where one has to respect needs such like maintainability, one typically does not want to handle more than two or three levels of indirection in one single expression—no matter which method of indirection is used.
Instead, one can resolve higher levels of indirection by using a loop to iterate something like
value=$variable
variable=$!value
a number of times that is suitable for the given application.
add a comment |
up vote
0
down vote
up vote
0
down vote
Actually, there is a further method to do indirections in Bash, at least effectively: If you have a=1
and b=a
, you can get the value of a
through b
like so:
eval echo $$b
This can be nested several times:
$ a=1; b=a; c=b; d=c
$ eval eval eval echo \\\$\$$$d
1
Here are the rules to find the right number of backslashes on each level:
- On the innermost level, no backslashes are used.
- On any other level, use 2 n + 1 backslashes, where n is the number of backslashes that are used on the next inner level.
Rationale: Rule 1 is trivial. Rule 2 comes from the fact that you have to apply one backslash more that in the next inner level while you have to escape all those that are not consumed in the current level, i.e. all but one.
As a consequence, the number of needed backslashes diverges exponentially with increasing number of levels so that nesting reaches its limit rather soon for this method.
But one has to emphasize here that this limit is of rather academic nature. In practice, where one has to respect needs such like maintainability, one typically does not want to handle more than two or three levels of indirection in one single expression—no matter which method of indirection is used.
Instead, one can resolve higher levels of indirection by using a loop to iterate something like
value=$variable
variable=$!value
a number of times that is suitable for the given application.
Actually, there is a further method to do indirections in Bash, at least effectively: If you have a=1
and b=a
, you can get the value of a
through b
like so:
eval echo $$b
This can be nested several times:
$ a=1; b=a; c=b; d=c
$ eval eval eval echo \\\$\$$$d
1
Here are the rules to find the right number of backslashes on each level:
- On the innermost level, no backslashes are used.
- On any other level, use 2 n + 1 backslashes, where n is the number of backslashes that are used on the next inner level.
Rationale: Rule 1 is trivial. Rule 2 comes from the fact that you have to apply one backslash more that in the next inner level while you have to escape all those that are not consumed in the current level, i.e. all but one.
As a consequence, the number of needed backslashes diverges exponentially with increasing number of levels so that nesting reaches its limit rather soon for this method.
But one has to emphasize here that this limit is of rather academic nature. In practice, where one has to respect needs such like maintainability, one typically does not want to handle more than two or three levels of indirection in one single expression—no matter which method of indirection is used.
Instead, one can resolve higher levels of indirection by using a loop to iterate something like
value=$variable
variable=$!value
a number of times that is suitable for the given application.
edited 2 days ago
answered 2 days ago
Jürgen
717
717
add a comment |
add a comment |
up vote
0
down vote
There is a (large) indirection allowed directly in arithmetic expansion for only numbers.
$ a=123 b=a c=b d=c e=d ; echo $((e))
123
you could expand it with declare:
$ jj=123; for ii in a..fa..z; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
123
But it is not infinite:
$ jj=123; for ii in a..za..z; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
bash: tz: expression recursion level exceeded (error token is "tz")
Is that enough?
add a comment |
up vote
0
down vote
There is a (large) indirection allowed directly in arithmetic expansion for only numbers.
$ a=123 b=a c=b d=c e=d ; echo $((e))
123
you could expand it with declare:
$ jj=123; for ii in a..fa..z; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
123
But it is not infinite:
$ jj=123; for ii in a..za..z; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
bash: tz: expression recursion level exceeded (error token is "tz")
Is that enough?
add a comment |
up vote
0
down vote
up vote
0
down vote
There is a (large) indirection allowed directly in arithmetic expansion for only numbers.
$ a=123 b=a c=b d=c e=d ; echo $((e))
123
you could expand it with declare:
$ jj=123; for ii in a..fa..z; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
123
But it is not infinite:
$ jj=123; for ii in a..za..z; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
bash: tz: expression recursion level exceeded (error token is "tz")
Is that enough?
There is a (large) indirection allowed directly in arithmetic expansion for only numbers.
$ a=123 b=a c=b d=c e=d ; echo $((e))
123
you could expand it with declare:
$ jj=123; for ii in a..fa..z; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
123
But it is not infinite:
$ jj=123; for ii in a..za..z; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
bash: tz: expression recursion level exceeded (error token is "tz")
Is that enough?
answered 2 days ago
Isaac
9,70311445
9,70311445
add a comment |
add a comment |
avidenat is a new contributor. Be nice, and check out our Code of Conduct.
avidenat is a new contributor. Be nice, and check out our Code of Conduct.
avidenat is a new contributor. Be nice, and check out our Code of Conduct.
avidenat is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f483207%2fhow-many-levels-of-indirection-can-i-apply-in-bash%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown