/bin/sh 함수의 마지막 매개변수를 얻는 방법

/bin/sh 함수의 마지막 매개변수를 얻는 방법

이것을 구현하는 더 좋은 방법은 무엇입니까 print_last_arg?

#!/bin/sh

print_last_arg () {
    eval "echo \${$#}"  # this hurts
}

print_last_arg foo bar baz
# baz

(그렇다면 어떻게 해야 할지 알 #!/usr/bin/zsh것입니다 #!/bin/sh. 내 문제는 이를 달성하기 위한 합리적인 방법을 찾는 것입니다 #!/bin/sh.)

편집: 위의 내용은 어리석은 예일 뿐입니다. 내 목표는인쇄마지막 매개변수이지만 쉘 함수에서 마지막 매개변수를 참조하는 방법이 있습니다.


편집 2:이렇게 명확하지 않은 질문에 대해 사과드립니다. 이번에는 제대로 해결되길 바랍니다.

만약 이것이 /bin/zsh대신에 /bin/sh, 나는 이런 것을 쓸 수 있었을 것입니다

#!/bin/zsh

print_last_arg () {
    local last_arg=$argv[$#]
    echo $last_arg
}

표현은 $argv[$#]첫 번째 편집에서 설명한 예입니다.쉘 함수에서 마지막 매개변수를 인용하는 방법.

따라서 원래 예제를 다음과 같이 작성했어야 했습니다.

print_last_arg () {
    local last_arg=$(eval "echo \${$#}")   # but this hurts even more
    echo $last_arg
}

...내가 원하는 것이 무엇인지 명확히 하기 위해 과제의 오른쪽에 덜 무서운 것이 배치되어 있습니다.

그러나 모든 예에서 마지막 매개변수에 액세스된다는 점에 유의하세요.비파괴적으로. IOW, 마지막 매개변수에 액세스해도 전체 위치 매개변수에 영향을 미치지 않습니다.

답변1

여는 기둥(공백 없는 위치 매개변수)을 제공하는 예:

print_last_arg foo bar baz

기본 항목의 경우 IFS=' \t\n'다음과 같습니다.

args="$*" && printf '%s\n' "${args##* }"

보다 안전하게 확장하려면 "$*"IFS를 설정하십시오(@StéphaneChazelas 기준).

( IFS=' ' args="$*" && printf '%s\n' "${args##* }" )

그러나 위치 매개변수에 공백이 포함될 수 있으면 위 방법은 실패합니다. 이 경우 다음을 사용하십시오.

for a in "$@"; do : ; done && printf '%s\n' "$a"

이러한 기술은 회피 eval되며 부작용이 없습니다.

테스트 대상shellcheck.net

답변2

이 질문은 2년이 넘었지만 좀 더 간단한 옵션을 공유하고 싶다고 생각했습니다.

print_last_arg () {
    echo "${@:${#@}:${#@}}"
}

실행해보자

print_last_arg foo bar baz
baz

불다쉘 매개변수 확장.

편집하다

더욱 간결하게 말하면: echo "${@: -1}"

(공간에 주목하세요)

원천

macOS 10.12.6에서 테스트되었지만 사용 가능한 대부분의 *nix 버전에서는 마지막 인수도 반환해야 합니다...

훨씬 덜 해롭다¯\_(ツ)_/¯

답변3

간단한 방법은 다음과 같습니다.

print_last_arg () {
  if [ "$#" -gt 0 ]
  then
    s=$(( $# - 1 ))
  else
    s=0
  fi
  shift "$s"
  echo "$1"
}

(인수가 전달되지 않았을 때 원본 버전이 실패했다는 @cuonglm의 요점을 기반으로 업데이트되었습니다. 이제 빈 줄이 에코됩니다. else필요한 경우 절의 동작을 변경하세요.)

답변4

이는 모든 POSIX 호환 셸은 물론 기존 POSIX 이전 Solaris Bourne 셸에서도 작동합니다.

do=;for do do :;done;printf "%s\n" "$do"

다음은 동일한 접근 방식을 기반으로 한 함수입니다.

print_last_arg()
  if [ "$*" ]; then
    for do do :;done
    printf "%s\n" "$do"
  else
    echo
  fi

추신: 함수 본문 주위에 중괄호를 잊어버렸다고 말하지 마세요 ;-)

관련 정보