매개변수를 이동하고 args ls에서 완전히 던지는 방법은 무엇입니까?

매개변수를 이동하고 args ls에서 완전히 던지는 방법은 무엇입니까?

N 매개변수를 가져오는 스크립트가 있습니다. 먼저 이를 구문 분석하고(특정 값을 추출한 다음 X) 해당 값을 사용하여 다른 프로그램을 호출합니다.

function main() {
    parse "$@"
    run "$@"
}
main "$@"

인수 목록 시작 부분에 선택적 매개변수(실행 중인 Python 버전을 설정하는 매개변수)를 추가하고 싶습니다. 그래서 이것을 구문 분석 기능에 추가했습니다.

if [ "$1" = '2' ] || [ "$1" = '3' ]; then version=$1 && shift; else version=2; fi

shift그러나 구문 분석이 끝난 후에는 실행 기능에 영향을 미치지 않기 때문에 멈춰 있습니다 . 첫 번째 값의 값을 다시 확인하지 않고 이 작업을 수행하려면 어떻게 해야 합니까(이렇게 하면 구문 분석 기능을 갖는 전체 목적이 무산됩니다)

답변1

각 셸 함수의 범위(및 스크립트의 최상위 코드 범위)에는 고유한 범위가 있습니다.위치 매개변수, 자체에만 직접 액세스할 수 있습니다. 가장 깔끔한 해결책은 관심 있는 위치 매개변수의 값을정렬. 그런 다음 여러 함수 범위에서 해당 배열을 읽고 수정할 수도 있습니다.

예를 들어, 스크립트 시작 부분에 다음 코드가 표시되도록 할 수 있습니다.

declare -a args=("$@")
  • 원하는 대로 배열 이름을 지정하십시오. 호출할 필요는 없습니다 args.
  • declare -a원한다면 생략할 수도 있습니다 .
  • 실제로 처음 부분에 나타날 필요는 없습니다. 그래야만 해달리다액세스하는 코드가 args실행되기 전에. 를 사용하는 쉘 함수의 정의 아래에 나타날 수도 있습니다 args. 명확성을 위해 시작 부분 근처에 배치하는 것이 좋습니다.

args그런 다음 여러 함수에서 배열을 작업할 수 있습니다 . 함수에 전달할 필요는 없습니다. 그들은 이미 그것에 접근할 수 있을 것입니다. 셸 함수의 코드가 내용을 수정한 args후 반환되면 호출자의 코드에서 변경 사항을 관찰할 수 있습니다.

Bash를 포함한 Bourne 스타일 쉘의 위치 매개변수는 1 기반 인덱싱을 사용합니다. ( $0프로그램 이름으로 확장되는 은 기술적으로 위치 매개변수가 아니며 함수 범위에서 변경되지 않기 때문입니다.) 그러나 Bash의 배열은 0 기반 인덱싱을 사용합니다. 따라서 , args=("$@")match $1, ${args[0]}match $2, ${args[1]}match $3${args[2]}이후에 계속됩니다. 예상한 대로 $@여전히 일치합니다 .${args[@]}

가독성을 위해 따옴표 없이 그런 식으로 썼습니다. 물론 args위치 매개변수와 관련된 확장을 거의 항상 큰따옴표로 묶고 싶은 것처럼 배열과 관련된 확장도 큰따옴표로 묶기를 원할 것입니다.

이 접근 방식을 사용하기로 결정한 경우 대신 다음을 수행하십시오.

shift

당신은 다음과 같이 쓸 것이다:

args=("${args[@]:1}")

Bash의 배열이 처음이라면 다음을 살펴보세요.Bash 참조 매뉴얼의 관련 부분. 대화형으로 실험해 볼 수도 있습니다. 예를 들어:

ek@Cord:~$ args=('foo bar' 'baz quux' 'ham spam')
ek@Cord:~$ printf '[%s]\n' "${args[@]}"
[foo bar]
[baz quux]
[ham spam]
ek@Cord:~$ printf '[%s]\n' "${args[@]:1}"
[baz quux]
[ham spam]

에 해당하는 코드

if [ "$1" = 2 ] || [ "$1" = 3 ]; then
    version="$1"
    shift
else
    version=2
fi

다음과 같습니다:

if [ "${args[0]}" = 2 ] || [ "${args[0]}" = 3 ]; then
    version="${args[0]}"
    args=("${args[@]:1}")
else
    version=2
fi

배열을 사용하는 것은 구문적으로 더 번거롭지만 더 유연합니다.

반면에 스크립트 코드의 대부분은 함수 run와 해당 피호출자로 구성되어 있으므로 특수 명령줄 인수를 구문 분석하는 대안을 고려할 수도 있습니다.~ 전에셸 함수 외부에서 을 호출한 run다음 run "$@"이미 수행 중인 대로 호출합니다.

거의 모든 것을 작고 독립적인 기능에 넣는 강한 윤리를 갖고 있는 관련 문화를 가진 프로그래밍 언어가 있습니다. Bash는 그러한 언어가 아니며, 쉘 함수에서 복잡한 데이터를 반환하는 제한된 방법이 그 이유 중 하나입니다. 쉘 함수를 작성하는 것을 두려워해서는 안 되며, 수많은 작은 쉘 함수를 기꺼이 작성해야 합니다. 하지만 스크립트에 가장 적합한 형식이 다른 것으로 판명되더라도 걱정할 필요는 없다고 생각합니다.

더 자세한 내용과 프로세스 대체 결과를 소스로 사용하는 이상한 접근 방식을 포함한 몇 가지 대안을 보려면 다음을 참조하세요.질의 답변에게함수 호출자 위치 매개변수.

관련 정보