Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.unix.shell > #26900 > unrolled thread
| Started by | Frank Winkler <usenet@f.winkler-ka.de> |
|---|---|
| First post | 2026-06-12 09:30 +0200 |
| Last post | 2026-06-24 11:41 +0000 |
| Articles | 20 on this page of 22 — 9 participants |
Back to article view | Back to comp.unix.shell
Variable var names Frank Winkler <usenet@f.winkler-ka.de> - 2026-06-12 09:30 +0200
Re: Variable var names gazelle@shell.xmission.com (Kenny McCormack) - 2026-06-12 09:02 +0000
Re: Variable var names Frank Winkler <usenet@f.winkler-ka.de> - 2026-06-13 12:29 +0200
Re: Variable var names gazelle@shell.xmission.com (Kenny McCormack) - 2026-06-13 11:14 +0000
Re: Variable var names Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-06-13 13:15 +0200
Re: Variable var names ram@zedat.fu-berlin.de (Stefan Ram) - 2026-06-12 11:26 +0000
Re: Variable var names ram@zedat.fu-berlin.de (Stefan Ram) - 2026-06-12 11:38 +0000
Re: Variable var names Frank Winkler <usenet@f.winkler-ka.de> - 2026-06-12 14:07 +0200
Re: Variable var names ram@zedat.fu-berlin.de (Stefan Ram) - 2026-06-12 12:31 +0000
Re: Variable var names Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-13 02:48 +0000
Re: Variable var names Christian Weisgerber <naddy@mips.inka.de> - 2026-06-12 12:12 +0000
Re: Variable var names Frank Winkler <usenet@f.winkler-ka.de> - 2026-06-12 15:19 +0200
Re: Variable var names Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-13 02:51 +0000
Re: Variable var names Geoff Clare <geoff@clare.See-My-Signature.invalid> - 2026-06-12 13:42 +0100
Re: Variable var names Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-06-12 17:41 +0200
Re: Variable var names Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-06-12 17:54 +0200
Re: Variable var names Frank Winkler <usenet@f.winkler-ka.de> - 2026-06-13 12:32 +0200
Re: Variable var names Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-14 01:12 +0000
Re: Variable var names Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-13 00:20 +0000
Re: Variable var names Kaz Kylheku <046-301-5902@kylheku.com> - 2026-06-23 21:25 +0000
Re: Variable var names Helmut Waitzmann <nn.throttle@erine.email> - 2026-06-24 10:45 +0200
Re: Variable var names Christian Weisgerber <naddy@mips.inka.de> - 2026-06-24 11:41 +0000
Page 1 of 2 [1] 2 Next page →
| From | Frank Winkler <usenet@f.winkler-ka.de> |
|---|---|
| Date | 2026-06-12 09:30 +0200 |
| Subject | Variable var names |
| Message-ID | <n91qs8Fk65fU1@mid.individual.net> |
Hi there ! I'm playing with the following in an interactive bash as well as in a ksh script: $ n=1 $ x1=" ok " $ x2=" not ok " $ eval echo \$x$n ok $ eval echo "\$x$n" ok $ n=2 $ eval echo "\$x$n" not ok $ So the variable var name seems to work but why are the blanks "deleted" here? I also tried some variants with "printf", but also with no success. Just out of curiosity, I tried this: $ IFS="" eval echo ".\$x$n." . not ok . $ To my surprise, it works but why is IFS relevant here? And to my even bigger surprise, it looks like everything seems to behave as expected in the bash session but in the ksh script, IFS is not just changed for this single command but globally - so I had to save and restore it to prevent the whole script from exploding. This makes the interesting part much longer and more complicated, eating up the potential advantage and coolness superiority over just doing something like [ $n -eq 1 ] && echo "$x1" [ $n -eq 2 ] && echo "$x2" Any hints from the experts? TIA Frank
[toc] | [next] | [standalone]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2026-06-12 09:02 +0000 |
| Message-ID | <110ghv7$2175u$1@news.xmission.com> |
| In reply to | #26900 |
In article <n91qs8Fk65fU1@mid.individual.net>, Frank Winkler <usenet@f.winkler-ka.de> wrote: >Hi there ! > >I'm playing with the following in an interactive bash as well as in a >ksh script: > >$ n=1 >$ x1=" ok " >$ x2=" not ok " >$ eval echo \$x$n >ok >$ eval echo "\$x$n" >ok >$ n=2 >$ eval echo "\$x$n" >not ok >$ > >So the variable var name seems to work but why are the blanks "deleted" >here? I also tried some variants with "printf", but also with no success. I don't know much about ksh, but in bash, you can (and, IMHO, you should) use the "nameref" functionality. I just did: $ declare -n foo $ n=1;x1=" ok ";x2=" not ok " $ for foo in x$n;do echo "|$foo|";done | ok | $ ((n++));for foo in x$n;do echo "|$foo|";done | not ok | $ Note that you have to use a "for" loop to get around a bit of the weirdness of how namerefs work in bash. I think both "eval" and "IFS" should be avoided if at all possible. Too many gotchas associated with both of these constructs. -- There are many self-professed Christians who seem to think that because they believe in Jesus' sacrifice they can reject Jesus' teachings about how we should treat others. In this country, they show that they reject Jesus' teachings by voting for Republicans.
[toc] | [prev] | [next] | [standalone]
| From | Frank Winkler <usenet@f.winkler-ka.de> |
|---|---|
| Date | 2026-06-13 12:29 +0200 |
| Message-ID | <n94pobF3vrqU1@mid.individual.net> |
| In reply to | #26902 |
On 12.06.2026 11:02, Kenny McCormack wrote: >I don't know much about ksh, but in bash, you can (and, IMHO, you should) >use the "nameref" functionality. I'm still trying to figure out how exactly that works ... ut thanks for the hint! Frank
[toc] | [prev] | [next] | [standalone]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2026-06-13 11:14 +0000 |
| Message-ID | <110je2v$264ji$1@news.xmission.com> |
| In reply to | #26920 |
In article <n94pobF3vrqU1@mid.individual.net>, Frank Winkler <usenet@f.winkler-ka.de> wrote: >On 12.06.2026 11:02, Kenny McCormack wrote: > > >I don't know much about ksh, but in bash, you can (and, IMHO, you should) > >use the "nameref" functionality. > >I'm still trying to figure out how exactly that works ... but thanks for >the hint! It *is* tricky and unintuitive in many ways, but it can be handy, once you get familiar with it. Note, BTW, that I chose to focus on the "Variable var names" aspect of your original post (that which is actually mentioned in the Subject: line), while most of the other responders have focussed on the "What happened to my leading and trailing blanks?" aspect of it. I consider that later aspect to be trivial and just a simple lack of understanding and care about shell quoting on your part. -- The randomly chosen signature file that would have appeared here is more than 4-ish lines long. As such, it violates one or more Usenet RFCs. In order to remain in compliance with said RFCs, the actual sig can be found at the following URL: http://user.xmission.com/~gazelle/Sigs/BestCLCPostEver
[toc] | [prev] | [next] | [standalone]
| From | Janis Papanagnou <janis_papanagnou+ng@hotmail.com> |
|---|---|
| Date | 2026-06-13 13:15 +0200 |
| Message-ID | <110je4o$2097v$4@dont-email.me> |
| In reply to | #26920 |
On 2026-06-13 12:29, Frank Winkler wrote:
> On 12.06.2026 11:02, Kenny McCormack wrote:
>
> >I don't know much about ksh, but in bash, you can (and, IMHO, you
> should)
> >use the "nameref" functionality.
>
> I'm still trying to figure out how exactly that works ... ut thanks for
> the hint!
With ksh93 Kornshell introduced "namerefs" as 'typeset -n' or as
alias 'nameref' as alternate form. They were mainly introduced to
support the concept of _reference parameters_ for functions.
function change_it
{
nameref one=$1 # arg1 is a variable (reference) name
one="new value"
}
var="old value"
change_it var # pass a variable name as reference
echo $var
Above the 'var' passed to the function can be changed within the
function if the respective argument is declared as reference.
Within the function you use the reference name but actually the
function operates on the variable whose name has been provided
with the function call. That way you can use the same function
to change various variables (and does not require to use an own
[unsafe] 'eval'-based mechanism to emulate such a functionality.)
Janis
[toc] | [prev] | [next] | [standalone]
| From | ram@zedat.fu-berlin.de (Stefan Ram) |
|---|---|
| Date | 2026-06-12 11:26 +0000 |
| Message-ID | <spaces-20260612122522@ram.dialup.fu-berlin.de> |
| In reply to | #26900 |
Frank Winkler <usenet@f.winkler-ka.de> wrote or quoted: >So the variable var name seems to work but why are the blanks "deleted" >here? Just on --03-15, I wrote here: |Nuno Silva <nunojsilva@invalid.invalid> writes: |>«One last note: echo itself will mangle leading spaces, | |When you input "echo $x", the shell substitutes "$x" by the value of |x with leading and trailing spaces stripped. The shell, not echo! .
[toc] | [prev] | [next] | [standalone]
| From | ram@zedat.fu-berlin.de (Stefan Ram) |
|---|---|
| Date | 2026-06-12 11:38 +0000 |
| Message-ID | <dots-20260612123818@ram.dialup.fu-berlin.de> |
| In reply to | #26905 |
ram@zedat.fu-berlin.de (Stefan Ram) wrote or quoted: >|When you input "echo $x", the shell substitutes "$x" by the value of >|x with leading and trailing spaces stripped. The shell, not echo! Using bash on trixie, I get $x=" a " $echo $x a $echo "$x" a $echo ".$x." . a . $eval echo \$x a $eval echo "\$x" a $eval echo ".\$x." . a . . So, the behavior of IFS probably is due to the dots "." used.
[toc] | [prev] | [next] | [standalone]
| From | Frank Winkler <usenet@f.winkler-ka.de> |
|---|---|
| Date | 2026-06-12 14:07 +0200 |
| Message-ID | <n92b4dFmk8aU1@mid.individual.net> |
| In reply to | #26906 |
On 12.06.2026 13:38, Stefan Ram wrote: >> |x with leading and trailing spaces stripped. The shell, not echo! Sure - and that's why I also quoted the variable, which should keep the blanks - shouldn't it? > . So, the behavior of IFS probably is due to the dots "." used. No, it's not. I just added the dots here to clarify that the blanks get lost.
[toc] | [prev] | [next] | [standalone]
| From | ram@zedat.fu-berlin.de (Stefan Ram) |
|---|---|
| Date | 2026-06-12 12:31 +0000 |
| Message-ID | <IFS-20260612133027@ram.dialup.fu-berlin.de> |
| In reply to | #26907 |
Frank Winkler <usenet@f.winkler-ka.de> wrote or quoted: > >. So, the behavior of IFS probably is due to the dots "." used. >No, it's not. I just added the dots here to clarify that the blanks get >lost. Sorry, I misread the whole IFS line. Now, I tried, $ x=" a " $ eval echo "\$x" a $ IFS="" eval echo \$x a . When the shell executes 'echo $x' after the input 'eval echo "\$x"', the quotes were already stripped during the preceding shell expansion. So, eval sees an unquoted '$x'. In evaluation of 'echo $x' by eval, word splitting happens, which removes the blanks. But when IFS is empty, no word splitting happens. |Word splitting begins by removing sequences of IFS whitespace |characters from the beginning and end of the results of the |previous expansions Word Splitting (Bash Reference Manual) |When IFS is empty (nullstring), no word splitting is |performed at all. Word splitting - The Bash Hackers Wiki
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-06-13 02:48 +0000 |
| Message-ID | <110igei$2l83v$1@dont-email.me> |
| In reply to | #26909 |
On 12 Jun 2026 12:31:20 GMT, Stefan Ram wrote: > Word splitting - The Bash Hackers Wiki Remember that every command gets, not a simple string, but an array of strings as its arguments. This applies to shell builtin commands as well.
[toc] | [prev] | [next] | [standalone]
| From | Christian Weisgerber <naddy@mips.inka.de> |
|---|---|
| Date | 2026-06-12 12:12 +0000 |
| Message-ID | <slrn112nttv.1fqc.naddy@lorvorc.mips.inka.de> |
| In reply to | #26900 |
On 2026-06-12, Frank Winkler <usenet@f.winkler-ka.de> wrote: > $ n=1 > $ x1=" ok " > $ x2=" not ok " > $ eval echo \$x$n > ok > $ eval echo "\$x$n" > ok > $ n=2 > $ eval echo "\$x$n" > not ok > $ > > So the variable var name seems to work but why are the blanks "deleted" > here? The usual expansion, quote stripping, etc. happen, producing echo $x1 echo $x2 which are then evaluated again. You need to quote the quote characters so they make it to the second round: $ eval echo \"\$x$n\" not ok > Just out of curiosity, I tried this: > > $ IFS="" eval echo ".\$x$n." > . not ok . > $ > > To my surprise, it works but why is IFS relevant here? The result of substituting $x2 is subject to field splitting according to the input field separators (IFS). > And to my even bigger surprise, it looks like everything seems > to behave as expected in the bash session but in the ksh script, > IFS is not just changed for this single command but globally - The latter is actually the POSIX-mandated behavior: "If the command name is a special built-in utility, variable assignments shall affect the current execution environment before the utility is executed and remain in effect when the command completes". Bash chooses to violate this, unless invoked with --posix or POSIXLY_CORRECT. The key term here is _special built-in_, as opposed to regular built-ins. The POSIX list of special built-ins is break, :, continue, ., eval, exec, exit, export, readonly, return, set, shift, times, trap, unset -- Christian "naddy" Weisgerber naddy@mips.inka.de
[toc] | [prev] | [next] | [standalone]
| From | Frank Winkler <usenet@f.winkler-ka.de> |
|---|---|
| Date | 2026-06-12 15:19 +0200 |
| Message-ID | <n92falFnb3cU1@mid.individual.net> |
| In reply to | #26908 |
On 12.06.2026 14:12, Christian Weisgerber wrote: >which are then evaluated again. You need to quote the quote >characters so they make it to the second round: > >$ eval echo \"\$x$n\" > not ok You're absolutely right - I really (sh|c)ould have had this idea by myself ;) ... >The result of substituting $x2 is subject to field splitting according >to the input field separators (IFS). Thanks for waking me up, Christian! :) >The latter is actually the POSIX-mandated behavior: "If the command >name is a special built-in utility, variable assignments shall >affect the current execution environment before the utility is >executed and remain in effect when the command completes". > >Bash chooses to violate this, unless invoked with --posix or >POSIXLY_CORRECT. Thanks for that info - I wasn't aware of that! Regards Frank
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-06-13 02:51 +0000 |
| Message-ID | <110igja$2l83v$2@dont-email.me> |
| In reply to | #26908 |
On Fri, 12 Jun 2026 12:12:47 -0000 (UTC), Christian Weisgerber wrote: > The latter is actually the POSIX-mandated behavior: "If the command > name is a special built-in utility, variable assignments shall > affect the current execution environment before the utility is > executed and remain in effect when the command completes". Sometimes, you must remember, a standard like POSIX has to codify existing behaviour, not because it’s the best behaviour, but because it’s the most common behaviour (or the common behaviour among products from companies which are/were the biggest marketing heavyweights at the time). > Bash chooses to violate this, unless invoked with --posix or > POSIXLY_CORRECT. Because who can remember the difference between a “special” or “regular” built-in?
[toc] | [prev] | [next] | [standalone]
| From | Geoff Clare <geoff@clare.See-My-Signature.invalid> |
|---|---|
| Date | 2026-06-12 13:42 +0100 |
| Message-ID | <4fbtfm-c51.ln1@ID-313840.user.individual.net> |
| In reply to | #26900 |
Frank Winkler wrote: > I'm playing with the following in an interactive bash as well as in a > ksh script: > > $ n=1 > $ x1=" ok " > $ x2=" not ok " > $ eval echo \$x$n > ok > $ eval echo "\$x$n" > ok > $ n=2 > $ eval echo "\$x$n" > not ok > $ > > So the variable var name seems to work but why are the blanks "deleted" > here? After eval interprets: eval echo "\$x$n" the command to be executed by the shell (with n=1) is: echo $x1 In order to quote the argument passed to echo, you need to supply some quotes that will survive the parsing that eval does: $ n=1 $ x1=" ok " $ eval echo "\"\$x$n\"" ok Here the command to be executed by the shell is: echo "$x1" > Just out of curiosity, I tried this: > > $ IFS="" eval echo ".\$x$n." > . not ok . > $ > > To my surprise, it works but why is IFS relevant here? Hopefully you can see why now, given the extra quotes in my example above. > And to my even > bigger surprise, it looks like everything seems to behave as expected in > the bash session but in the ksh script, IFS is not just changed for this > single command but globally - so I had to save and restore it to prevent > the whole script from exploding. This is actually required by POSIX. If you set POSIXLY_CORRECT=1 in the environment, bash does the same. (It's required for the "special built-in utilities", of which eval is one.) -- Geoff Clare <netnews@gclare.org.uk>
[toc] | [prev] | [next] | [standalone]
| From | Janis Papanagnou <janis_papanagnou+ng@hotmail.com> |
|---|---|
| Date | 2026-06-12 17:41 +0200 |
| Message-ID | <110h9bv$2097u$1@dont-email.me> |
| In reply to | #26900 |
On 2026-06-12 09:30, Frank Winkler wrote:
> Hi there !
You've already got a couple useful hints and explanations. So just
some additional hints...
Below, consider using arrays instead of manipulating variable names.
(Thereby you avoid the 'eval' that you've already been suggested to
avoid in the first place, if not really necessary.)
x=( "" " ok " " not ok " )
echo ${x[1]}
echo ${x[2]}
Standard arrays are counted from 0 so the first array element has
a dummy element above. (Modern shells also support associative
arrays, in case you want more flexibility.)
If you want for (some reason) to use 'eval' note that you can, as
suggested, use two layers of quotes (one escaped), or just use two
different nested quotes ( " and ' ), but also note the effects of
expansions inside the double-quotes; you can take that for your
advantage (if you know the expansion rules).
The effect of IFS changes on _internal_ shell commands like 'eval'
have been explained already, and that this is standard behavior.
Note that you don't need to save/restore the IFS in standard code;
you can also embed it in a subshell-environment with parenthesis
to keep the IFS change local within the parenthesis, as in
( IFS="" eval echo ".\$x$n." )
In ksh you won't create a real subshell that way if there's only
shell built-ins like 'eval' and 'echo' used, so it's efficient.
If you intend to use mainly "modern" shells like bash, ksh, zsh,
you should consider using (instead of [ ... ]) [[ ... ]], or in
case of arithmetic (as in your code below) the shell's arithmetic
statement
(( n == 1 )) && ..
For many values you may also use 'case',
case $n in
(1) ... ;;
(2) ... ;;
(*) ... ;; # default branch for errors
esac
And of course use 'printf' (instead of 'echo').
Janis
>
> I'm playing with the following in an interactive bash as well as in a
> ksh script:
>
> $ n=1
> $ x1=" ok "
> $ x2=" not ok "
> $ eval echo \$x$n
> ok
> $ eval echo "\$x$n"
> ok
> $ n=2
> $ eval echo "\$x$n"
> not ok
> $
>
> So the variable var name seems to work but why are the blanks "deleted"
> here? I also tried some variants with "printf", but also with no success.
>
> Just out of curiosity, I tried this:
>
> $ IFS="" eval echo ".\$x$n."
> . not ok .
> $
>
> To my surprise, it works but why is IFS relevant here? And to my even
> bigger surprise, it looks like everything seems to behave as expected in
> the bash session but in the ksh script, IFS is not just changed for this
> single command but globally - so I had to save and restore it to prevent
> the whole script from exploding. This makes the interesting part much
> longer and more complicated, eating up the potential advantage and
> coolness superiority over just doing something like
>
> [ $n -eq 1 ] && echo "$x1"
> [ $n -eq 2 ] && echo "$x2"
>
> Any hints from the experts?
>
> TIA
>
> Frank
>
[toc] | [prev] | [next] | [standalone]
| From | Janis Papanagnou <janis_papanagnou+ng@hotmail.com> |
|---|---|
| Date | 2026-06-12 17:54 +0200 |
| Message-ID | <110ha39$2097v$2@dont-email.me> |
| In reply to | #26913 |
On 2026-06-12 17:41, Janis Papanagnou wrote:
> On 2026-06-12 09:30, Frank Winkler wrote:
>> Hi there !
>
> You've already got a couple useful hints and explanations. So just
> some additional hints...
>
> Below, consider using arrays instead of manipulating variable names.
> (Thereby you avoid the 'eval' that you've already been suggested to
> avoid in the first place, if not really necessary.)
>
> x=( "" " ok " " not ok " )
> echo ${x[1]}
> echo ${x[2]}
And of course I forgot to mention (and also consider above) the most
basic rule; quote your variables. Above should of course have been
echo "${x[1]}"
echo "${x[2]}"
(and 'echo' also replaced by 'printf', of course). :-)
>
> Standard arrays are counted from 0 so the first array element has
> a dummy element above. (Modern shells also support associative
> arrays, in case you want more flexibility.)
>
> If you want for (some reason) to use 'eval' note that you can, as
> suggested, use two layers of quotes (one escaped), or just use two
> different nested quotes ( " and ' ), but also note the effects of
> expansions inside the double-quotes; you can take that for your
> advantage (if you know the expansion rules).
>
> The effect of IFS changes on _internal_ shell commands like 'eval'
> have been explained already, and that this is standard behavior.
> Note that you don't need to save/restore the IFS in standard code;
> you can also embed it in a subshell-environment with parenthesis
> to keep the IFS change local within the parenthesis, as in
>
> ( IFS="" eval echo ".\$x$n." )
>
> In ksh you won't create a real subshell that way if there's only
> shell built-ins like 'eval' and 'echo' used, so it's efficient.
>
> If you intend to use mainly "modern" shells like bash, ksh, zsh,
> you should consider using (instead of [ ... ]) [[ ... ]], or in
> case of arithmetic (as in your code below) the shell's arithmetic
> statement
>
> (( n == 1 )) && ..
>
> For many values you may also use 'case',
>
> case $n in
> (1) ... ;;
> (2) ... ;;
> (*) ... ;; # default branch for errors
> esac
>
> And of course use 'printf' (instead of 'echo').
>
> Janis
>
>>
>> I'm playing with the following in an interactive bash as well as in a
>> ksh script:
>>
>> $ n=1
>> $ x1=" ok "
>> $ x2=" not ok "
>> $ eval echo \$x$n
>> ok
>> $ eval echo "\$x$n"
>> ok
>> $ n=2
>> $ eval echo "\$x$n"
>> not ok
>> $
>>
>> So the variable var name seems to work but why are the blanks
>> "deleted" here? I also tried some variants with "printf", but also
>> with no success.
>>
>> Just out of curiosity, I tried this:
>>
>> $ IFS="" eval echo ".\$x$n."
>> . not ok .
>> $
>>
>> To my surprise, it works but why is IFS relevant here? And to my even
>> bigger surprise, it looks like everything seems to behave as expected
>> in the bash session but in the ksh script, IFS is not just changed for
>> this single command but globally - so I had to save and restore it to
>> prevent the whole script from exploding. This makes the interesting
>> part much longer and more complicated, eating up the potential
>> advantage and coolness superiority over just doing something like
>>
>> [ $n -eq 1 ] && echo "$x1"
>> [ $n -eq 2 ] && echo "$x2"
>>
>> Any hints from the experts?
>>
>> TIA
>>
>> Frank
>>
>
[toc] | [prev] | [next] | [standalone]
| From | Frank Winkler <usenet@f.winkler-ka.de> |
|---|---|
| Date | 2026-06-13 12:32 +0200 |
| Message-ID | <n94pukF416kU1@mid.individual.net> |
| In reply to | #26913 |
Many thanks also to all the other guys who provided useful stuff. Besides some "easy ones" I accidentally didn't think to an end, there were a couple of really new insights ;) ... Shell scripting is still a cool science of its own :) ... Regards Frank
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-06-14 01:12 +0000 |
| Message-ID | <110kv5r$3a32m$9@dont-email.me> |
| In reply to | #26921 |
On Sat, 13 Jun 2026 12:32:52 +0200, Frank Winkler wrote: > Shell scripting is still a cool science of its own :) ... Just so long as you don’t try to do *everything* with it ...
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-06-13 00:20 +0000 |
| Message-ID | <110i7p3$2iqm8$10@dont-email.me> |
| In reply to | #26900 |
On Fri, 12 Jun 2026 09:30:16 +0200, Frank Winkler wrote: > To my surprise, it works but why is IFS relevant here? And to my > even bigger surprise, it looks like everything seems to behave as > expected in the bash session but in the ksh script, IFS is not just > changed for this single command but globally - so I had to save and > restore it to prevent the whole script from exploding. If you’re using eval, that’s often a good sign you’re doing something wrong†. If you want indirect variable references, bash has “declare -n” for that purpose. †Except in Lisp. Because Lisp “eval” isn’t evaluating strings, but homoiconic list structures. There’s a lesson in there for other languages that naïvely try to copy the concept.
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <046-301-5902@kylheku.com> |
|---|---|
| Date | 2026-06-23 21:25 +0000 |
| Message-ID | <20260623140125.387@kylheku.com> |
| In reply to | #26900 |
On 2026-06-12, Frank Winkler <usenet@f.winkler-ka.de> wrote:
> Hi there !
>
> I'm playing with the following in an interactive bash as well as in a
> ksh script:
>
> $ n=1
> $ x1=" ok "
> $ x2=" not ok "
> $ eval echo \$x$n
> ok
> $ eval echo "\$x$n"
> ok
> $ n=2
> $ eval echo "\$x$n"
> not ok
> $
>
> So the variable var name seems to work but why are the blanks "deleted"
> here? I also tried some variants with "printf", but also with no success.
eval takes all of its arguments, and catenates them together as if by
spaces. The resulting string is a piece of shell syntax that is
lexically scanned and otherwise processed entirely from scratch, almost
as if the shell were reading input from the command line or a script
file.
First your arguments undergo substitutions, producing the arguments
for eval, like this:
echo \$x$n -> echo $x1
echo "\$x$n" -> echo $x2 # n was reassigned to 2
As you can see, the quoting disappears at this stage before eval
sees it! In both cases, eval sees the two pieces {echo} and {$x}.
These are turned into the syntax {echo $x}. This syntax is then
evaluated. Note that it has no quoting that would preserve
the blanks in the value of $x.
Note how you carefully preserved the dollar sign with a backslash
so that it is not swallowed by the first round of expansions.
You ensured that eval sees the dollar sign in $x1 and $x2.
In exactly the same manner, you must insert quoting in such a
way that it is preserved, for instance like this:
eval echo \"\$x$n\"
Now our first round of expansion, before eval is called
goes like this:
echo \"\$x$n\" -> echo "$x1"
That is the correct syntax for echoing x1 with the spaces preserved.
> Just out of curiosity, I tried this:
>
> $ IFS="" eval echo ".\$x$n."
> . not ok .
> $
>
> To my surprise, it works but why is IFS relevant here? And to my even
IFS="" does not kick in until eval executes. The syntax that is produced
is
echo .$x2.
With the default IFS, that would be subject to field spltting,
producing the four fields {.}{not}{ok}{.} which become separate
arguments of echo.
You've overriden IFS over the execution of eval, suppressing that field
splitting, so the expansion of .$x2. is taken as-is, a single argument,
containing spaces.
The value of IFS is relevant to the eval, because eval performs complete
processing of the syntax from scratch, including another round of
parameter expansion that takes place before echo is called. (Of course:
without that expansion we would not get the $x2 interpolation).
IFS speaks to the semantics of that parameter expansion.
> bigger surprise, it looks like everything seems to behave as expected in
> the bash session but in the ksh script, IFS is not just changed for this
> single command but globally - so I had to save and restore it to prevent
> the whole script from exploding.
You've run into a quirk of the VAR=value ... command ... syntax.
When you use that with an external command, like "CFLAGS=-O2 make",
it creates an environment binding over just that command. This is
a widely used, standardized feature that works "everywhere".
However, when VAR=value it is used on built-in commands, there are
pitfalls. It depends on which exact built-in command and what shell.
What the POSIX standard requires in regard to assignments in a command
can be found here:
https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html
in section "2.9.1.2 Variable Assignments".
As you can see, even in the case when the command is not a built-in
or function, there are some unspecified behaviors!
It is also written that "If the command name is a special built-in
utility, variable assignments shall affect the current execution
environment before the utility is executed and remain in effect when the
command completes". So in fact ksh is conforming, even though it
is arguably a dumb behavior that Bash disagrees with (even in --posix
mode; just tested with 4.4 and 5.1).
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.unix.shell
csiph-web