Question: I have this script which designed to download the pronounciation of the words you give it as argument:

```bash
#!/bin/bash 
m=$#
for ((i=1;i<=m;i++));do

echo $i
#wget https://ssl.gstatic.com/dictionary/static/sounds/de/0/"$i".mp3
done

```

if I run it by this command

```
./a.sh personality brave selfish

```

it should print on the stdout

```
personality 
brave 
selfish

```

but instead it prints

```
1
2
3

```

would you help me solve this problem?

p.s : If I write the script without for loop with $1 for example it will work correctly but I want to download many files at the same time

Answer: 
In any Bourne-like shell, it's:

```
for arg
do printf 'Something with "%s"\n' "$arg"
done

```

That is, `for` does loop on the positional parameters (`$1`, `$2`...) by default (if you don't give a `in ...` part).

Note that that's more portable than:

```
for arg; do
  printf 'Something with "%s"\n' "$arg"
done

```

Which was not POSIX until the 2016 edition of the standard nor Bourne (though works in most other Bourne-like shells including `bash` even in POSIX mode)

Or than:

```
for arg in "$@"; do
  printf 'Something with "%s"\n' "$arg"
done

```

Which is POSIX but doesn't work properly in the Bourne shell or ksh88 when `$IFS` doesn't contain the space character, or with some versions of the Bourne shell when there's no argument, or with some shells (including some versions of `bash`) when there's no argument and the `-u` option is enabled.

Or than

```
for arg do
  printf 'Something with "%s"\n' "$arg"
done

```

which is POSIX and Bourne but doesn't work in very old ash-based shells. I personally ignore that and use that syntax myself as I find it's the most legible and don't expect any of the code I write will ever end up interpreted by such an arcane shell.

More info at:

* <http://www.in-ulm.de/~mascheck/various/bourne_args/>
* [What is the purpose of the “do” keyword in Bash for loops?](/a/306944)

---

Now if you do want `$i` to loop over `[1..$#]` and access the corresponding elements, you can do:

in any POSIX shell:

```
i=1
for arg do
  printf '%s\n' "Arg $i: $arg"
  i=$((i + 1))
done

```

or:

```
i=1
while [ "$i" -le "$#" ]; do
  eval "arg=\${$i}"
  printf '%s\n' "Arg $i: $arg"
  i=$((i + 1))
done

```

Or with `bash`

```
for ((i = 1; i <= $#; i++ )); do
  printf '%s\n' "Arg $i: ${!i}"
done

```

`${!i}` being an indirect variable expansion, that is expand to the content of the parameter whose name is stored in the `i` variable, similar to `zsh`'s `P` parameter expansion flag:

```
for ((i = 1; i <= $#; i++ )); do
  printf '%s\n' "Arg $i: ${(P)i}"
done

```

Though in `zsh`, you can also access positional parameters via the `$argv` array (like in `csh`):

```
for ((i = 1; i <= $#; i++ )); do
  printf '%s\n' "Arg $i: $argv[i]"
done

```
Easiest way

```
#!/bin/bash
for i
do
 echo $i
done

```

and run 

```
./a.sh personality brave selfish

```

and here is the print on the stdout

```
personality
brave
selfish

```