2

I am looking for a sh equivalent of the following (yes, really.)

#!/bin/bash

exe1='filepath'
n=1
var=exe${n}
echo ${!var}

Where the echo should output filepath. I want to use plain sh.

I have already played around with the code a lot, but I didn't manage to get the output right so far.

I want to achieve an array-like structure, I'd just want to iterate over the variable name for a known number of variables using a loop.

For the array I found Arrays in a POSIX compliant shell but I'm still looking for the answer to the question for curiosity ;)

6
  • 2
    The POSIX shell has arrays! Well, it has one list, the list of positional parameters. Depending on what it is you'd want to do, this may be of use. Note that the code in your question has nothing to do with arrays in bash, but about indirection. If you could show a more complete example, we could show how to do the same with /bin/sh. – Kusalananda Dec 15 '19 at 16:45
  • The question is not about the arrays, so nothing to note here. – kaiya Dec 15 '19 at 16:47
  • 2
    Then why are you even mentioning arrays in the question and in comments? – Kusalananda Dec 15 '19 at 16:48
  • Since stackoverflow recommends writing down the motivation. Then I found another way for that, but that doesn't mean I am not interested in exactly what I was asking. – kaiya Dec 15 '19 at 16:52
  • 2
    Your code (as shown) does not use any lists, so I can't see how using the positional parameters would make it easier to read, sorry. – Kusalananda Dec 15 '19 at 17:01
5

An equivalent sh script to what's presented in the question:

#!/bin/sh

exe1='filepath'
n=1
var=exe$n
eval "echo \"\$$var\""   # or: eval 'echo "$'"$var"'"'

The eval line will evaluate the given string as a command in the current environment. The given string is echo \"\$$var\", which, after variables have been expanded etc., would become echo "$exe1". This is passed to eval for re-evaluation, and the command prints the string filepath.


You also mention arrays. It is true that the POSIX sh shell does not have named arrays in the same sense that e.g. bash has, but it still has the list of positional parameters.

With it, you can do most things that you'd need to do with a list in the shell.

For example,

set -- 'filepath1' 'filepath2' 'filepath3'

for name in "$@"; do    # or: for name do
    echo "$name"
done

which is the same as just

for name in 'filepath1' 'filepath2' 'filepath3'
do
    echo "$name"
done

Since I'm usure of what it is you're trying to achieve, I can't come up with a more interesting example. But here you have an array-like structure that you iterate over. Why you'd want to iterate over names of variables is still not clear.

1
  • Thanks, that was exactly the answer that I was looking for! – kaiya Dec 15 '19 at 17:29
-1

If you want to iterate over a number of files (implied from exe1=filepath in example) does a simple for loop work?

final_file is the variable holding the last file which matches the file_pattern - replicating bash's ${!var} (last argument referencing).

  #/bin/sh
  final_file=''
  file_pattern='*.txt'
  for f in $file_pattern
  do
      echo $f
      final_file=$f
  done
  echo $final_file
2
  • huh? this doesn't seem to respond at all to my question...? No, patterns won't do here, file paths are arbitrary. – kaiya Dec 15 '19 at 16:50
  • ok, why not arbitrary file_pattern="f1.txt a.out arbitrary.c README" ? – suspectus Dec 15 '19 at 17:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.