2

This is the script

user@linux:~$ cat script.sh 
#!/bin/bash
for i in `seq $#`
do
  echo $i
done
user@linux:~$ 

Output

user@linux:~$ ./script.sh a b c
1
2
3
user@linux:~$ 

Desired Output

I would like to get argument value like this .... and not just the number

user@linux:~$ ./script.sh a b c
1 - a
2 - b
3 - c
user@linux:~$ 
5
  • 1
    You included the bash tag, but gave your script a .sh extension, and the syntax of the file looks more like zsh (because of the unquoted variable expansions). Which is it? Jul 4, 2019 at 5:59
  • Thanks @StéphaneChazelas It's /bin/bash. I've updated my script above with shebang
    – user264359
    Jul 4, 2019 at 9:29
  • something got mixed up now, after deleting...the new "sabrina" question was AFTER a ls command at the prompt...anyway....is i=$((i + 1)) the way to increment? And what about $0?
    – user359065
    Jul 4, 2019 at 10:40
  • @sam68 Are you thinking of Sabrina's earlier question, which was closed as a duplicate of this one?
    – Jeff Schaller
    Jul 4, 2019 at 14:02
  • How can a duplicate be older (16h) than the already exisiting Q (11h)? And did you notice the echo $0 produced a "bash" in her output? I answered also that.
    – user359065
    Jul 4, 2019 at 17:08

2 Answers 2

4
#! /bin/sh -
i=1
for arg do
  printf '%2d: %s\n' "$i" "$arg"
  i=$((i + 1))
done

That is, instead of looping over the indexes, loop over the arguments and increment an index separately.

A few notes on your approach:

  • leaving a parameter expansion unquoted in list context has a very special meaning, you almost never want to do that.

  • echo can't be used to output arbitrary data.

  • The `...` form of command substitution should be avoided these days. Use $(...) instead.

  • Because unquoted command substitution also invokes split+glob, it has to be used with care. Here, you're using the split part which means you have a dependency on the current value of $IFS. The output of seq won't include wildcards, so you won't have a problem with the glob part.

  • seq is not a standard command and not found on all systems. To loop on numbers, it's not the best approach anyway, as that means storing the whole output in memory and split it (resulting in extra copies in memory), and that means running a separate utility in a separate process even though the shell has builtin support for that.

  • If you don't put any she-bang (#! /path/to/interpreter - first line), the only guarantee that you'll get is that it will be interpreted by a POSIX sh shell (in older systems, that could even be a Bourne (non-POSIX) shell), so you need to make sure the syntax you use is POSIX compliant. Even on systems where sh is provided by bash, not all bash extensions are enabled when running as sh.

    The code above is POSIX compliant (and would also work in bash) but not Bourne compatible (because of the $((...)) arithmetic expansion syntax which was not available in the Bourne shell). On Solaris 10 and older, you'd need to change the she-bang to #! /usr/xpg4/bin/sh - to get a (mostly) POSIX-compliant interpreter

1
#!/bin/bash
for ((i=1; i<=$#; i++))
do
  echo "$i - ${!i}"
done

You must log in to answer this question.