Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.unix.shell > #26900 > unrolled thread

Variable var names

Started byFrank Winkler <usenet@f.winkler-ka.de>
First post2026-06-12 09:30 +0200
Last post2026-06-24 11:41 +0000
Articles 20 on this page of 22 — 9 participants

Back to article view | Back to comp.unix.shell


Contents

  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 →


#26900 — Variable var names

FromFrank Winkler <usenet@f.winkler-ka.de>
Date2026-06-12 09:30 +0200
SubjectVariable 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]


#26902

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2026-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]


#26920

FromFrank Winkler <usenet@f.winkler-ka.de>
Date2026-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]


#26922

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2026-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]


#26923

FromJanis Papanagnou <janis_papanagnou+ng@hotmail.com>
Date2026-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]


#26905

Fromram@zedat.fu-berlin.de (Stefan Ram)
Date2026-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]


#26906

Fromram@zedat.fu-berlin.de (Stefan Ram)
Date2026-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]


#26907

FromFrank Winkler <usenet@f.winkler-ka.de>
Date2026-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]


#26909

Fromram@zedat.fu-berlin.de (Stefan Ram)
Date2026-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]


#26918

FromLawrence D’Oliveiro <ldo@nz.invalid>
Date2026-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]


#26908

FromChristian Weisgerber <naddy@mips.inka.de>
Date2026-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]


#26911

FromFrank Winkler <usenet@f.winkler-ka.de>
Date2026-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]


#26919

FromLawrence D’Oliveiro <ldo@nz.invalid>
Date2026-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]


#26910

FromGeoff Clare <geoff@clare.See-My-Signature.invalid>
Date2026-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]


#26913

FromJanis Papanagnou <janis_papanagnou+ng@hotmail.com>
Date2026-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]


#26914

FromJanis Papanagnou <janis_papanagnou+ng@hotmail.com>
Date2026-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]


#26921

FromFrank Winkler <usenet@f.winkler-ka.de>
Date2026-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]


#26924

FromLawrence D’Oliveiro <ldo@nz.invalid>
Date2026-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]


#26917

FromLawrence D’Oliveiro <ldo@nz.invalid>
Date2026-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]


#26925

FromKaz Kylheku <046-301-5902@kylheku.com>
Date2026-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