for 루프에서 $1 $2 ...와 같은 인수를 사용하는 방법은 무엇입니까?

for 루프에서 $1 $2 ...와 같은 인수를 사용하는 방법은 무엇입니까?

나는 당신이 인수로 제공한 단어의 발음을 다운로드하도록 설계된 다음 스크립트를 가지고 있습니다.

#!/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

이 명령으로 실행하면

./a.sh personality brave selfish

그것은 stdout에 인쇄되어야합니다

personality 
brave 
selfish

하지만 대신에 인쇄됩니다

1
2
3

이 문제를 해결하도록 도와주시겠어요?

ps: 예를 들어 $1을 사용하여 for 루프 없이 스크립트를 작성하면 올바르게 작동하지만 동시에 많은 파일을 다운로드하고 싶습니다.

답변1

Bourne과 같은 쉘에서는 다음과 같습니다.

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

즉, 기본적으로 위치 매개변수( , ...) for를 반복합니다 (부분을 지정하지 않은 경우 ).$1$2in ...

다음보다 이식성이 더 좋습니다.

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

2016년 표준 버전이나 Bourne까지는 POSIX가 아니었습니다( bashPOSIX 모드를 포함하여 대부분의 다른 Bourne 유사 셸에서도 작동하지만).

또는 다음보다:

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

POSIX이지만 $IFS공백 문자가 포함되지 않은 Bourne 쉘이나 ksh88에서, 인수가 없을 때 Bourne 쉘의 일부 버전에서 또는 인수가 bash없는 일부 쉘(일부 버전 포함) 에서 제대로 작동하지 않습니다. 인수가 있고 -u옵션이 활성화됩니다.

아니면

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

이는 POSIX 및 Bourne이지만 아주 오래된 재 기반 쉘에서는 작동하지 않습니다. 나는 개인적으로 그것을 무시하고 그 구문을 사용합니다. 왜냐하면 그것이 가장 읽기 쉽고 내가 작성한 코드 중 어떤 것도 그런 신비한 껍질에 의해 해석될 것이라고 기대하지 않기 때문입니다.

자세한 내용은 다음을 참조하세요.


이제 해당 요소를 $i반복 하고 액세스 하려면 다음을 수행할 수 있습니다.[1..$#]

모든 POSIX 셸에서:

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

또는:

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

아니면bash

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

${!i}간접 변수 확장입니다. 즉, 의 매개변수 확장 플래그 i와 유사하게 이름이 변수에 저장된 매개변수의 내용으로 확장됩니다 .zshP

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

에서는 배열 zsh을 통해 위치 매개변수에 액세스할 수도 있습니다 $argv(예 csh: ).

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

답변2

나는 shift. 이는 [ -n "$1" ]arg-1이 비어 있지 않은 동안 계속 반복한다는 의미입니다.

#! /bin/bash 
while [ -n "$1" ]; do
  echo "$1"
  wget "https://ssl.gstatic.com/dictionary/static/sounds/de/0/$1.mp3"
  shift
done

답변3

가장 쉬운 방법

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

그리고 달리다

./a.sh personality brave selfish

여기 stdout에 인쇄된 내용이 있습니다.

personality
brave
selfish

관련 정보