런타임까지 n을 알 수 없는 경우 스크립트의 n번째 인수를 인쇄하는 방법은 무엇입니까?

런타임까지 n을 알 수 없는 경우 스크립트의 n번째 인수를 인쇄하는 방법은 무엇입니까?

쉘 스크립트를 작성 중인데 스크립트의 n번째 매개변수를 인쇄해야 합니다.

n=3예를 들어, 충분한 매개변수를 사용하여 스크립트가 실행된다고 가정해 보겠습니다 . 이제 n번째 매개변수를 인쇄해야 합니다 $3.

그러나 만약 그렇다면 n=2우리는 매개변수를 인쇄할 것입니다 $2.

나는 진술을 사용하고 싶지 않습니다 if. 나는 다음과 같은 것을하고 싶다

echo $($n)

그러나 위의 방법은 내가 원하는 방식으로 작동하지 않습니다.

답변1

다양한 쉘에서 연대순으로:

  • csh (70년대 후반): ( $argv[$n]1991년 이후 zsh에서도 작동하고 2005년 이후 Fish에서도 작동함)
  • zsh (1991): $argv[n]// (마지막 것도 yash에서 지원되지만 추가 중괄호만 사용하면 됩니다 $@[n]: / )$*[n]${@[n]}${*[n]}
  • rc (90년대 초반): $$n/ $*($n)(es, akanga에도 적용됨)
  • ksh93 (1993): ${@:n:1}, ${*:n:1}(1996년부터 bash에서도 지원됨, zsh에서도 지원됨)2010년부터, csh 스타일 수정자와의 충돌이 필요 ${@:$n:1}하거나 방지하려면 다음을 참조하세요.${@: n:1}거기"$*"사건 에 대해 )
  • 배쉬(1996):${!n}
  • 지쉬(1999년): ${(P)n}.

ksh93/bash/yash에서는 최소한 목록 컨텍스트에서 매개변수 확장을 인용해야 하며 csh는 신뢰할 수 있는 코드를 작성하기 어렵다는 점을 명심하십시오.

목록 컨텍스트와 n번째 위치bash 인수가 설정되지 않은 경우에는 차이가 있습니다 . 후자는 전혀 인수 없이 확장되는 반면 전자는 빈 요소로 확장되기 때문입니다."${!n}""${@:n:1}"

Bourne과 같은 셸(Bourne 셸은 9번째 이상의 인덱스에서는 작동하지 않으므로 Bourne 셸은 아님)에서 표준 POSIX sh 구문을 사용하여 다음을 수행할 수도 있습니다.

eval "nth=\${$n}"

엄격하게 0보다 큰 정수의 표준 십진수 표현을 포함하지 않는 경우에도 동작이 모두 다릅니다. $n이것이 사실이라고 보장할 수 없다면 (하나가 아닌 eval) 대부분을 사용하면 임의의 명령 실행 취약점이 발생하게 됩니다(유일한 예외는 rc아마도 csh위의 경우일 것입니다).

zsh또한 (with echo -E - $argv[n]), yash(with ECHO_STYLE=raw echo "${*[$n]}") 및 fish(with echo -- $argv[$n]) 외에도echo임의의 데이터를 출력하는 데 사용할 수 없습니다. printf '%s\n' ...대신 사용하십시오.).

답변2

스크립트에 전달하는 매개변수는 배열에 저장되므로 @원하는 작업을 수행하는 쉬운 방법은 다음과 같습니다.배열 슬라이스, 위치에서 시작 n, 길이 1:

#!/bin/bash

n=3
echo "Argument $n: ${@:n:1}"

일부 매개변수를 사용하여 이 명령을 실행하면 다음과 같은 결과를 얻을 수 있습니다.

$ foo.sh a b c d e f
Argument 3: c

원래 요청한 또 다른 옵션은 "간접 확장"입니다.

#!/bin/bash

n=3
echo "Argument $n: ${!n}"

이것을 실행하세요:

$ foo.sh a b c d e f
Argument 3: c

답변3

변수 간접 참조를 사용할 수 있습니다.

#!/bin/bash
n=3
echo "${!n}"

답변4

간단한 휴대용 셸(bash 종속성 없음) 솔루션(명령의 잠재적인 결함을 모듈로 echo, 로 대체 가능 printf):

print_nth () {
    shift "$1"
    echo "$1"
}

그런 다음 다음을 수행하십시오.

print_nth "$n" "$@"

관련 정보