bash 스크립트에서 첫 번째 인수를 제외한 모든 인수를 처리하십시오.


444

첫 번째 인수가 파일 이름을 위해 예약 된 간단한 스크립트가 있으며 다른 모든 선택적 인수는 스크립트의 다른 부분으로 전달되어야합니다.

Google을 사용 하여이 위키를 찾았 지만 문자 그대로의 예를 제공했습니다.

echo "${@: -1}"

나는 다음과 같이 다른 일을 할 수 없다.

echo "${@:2}"

또는

echo "${@:2,1}"

터미널에서 "잘못된 대체"를 얻습니다.

문제는 무엇이며 첫 번째 인수를 제외한 모든 인수를 bash 스크립트에 어떻게 처리합니까?


21
혼란스러워하는 다른 사람을 불러 내기 위해 잘못된 shebang이 제공 "{@:2}"되어 작동하지 않아 올바른 답변이 위와 일치합니다.
Guvante

3
우분투와 다른 많은 리눅스에서는 기본 쉘을 사용했습니다. 대시에서 "$ {@ : -1}"은 다음과 같이 해석됩니다. {parameter : -word}-기본값을 사용하고 매개 변수가 정의되지 않았거나 널인 경우 단어를 사용하십시오. 따라서 대시 "$ {@ : -1}"은 "$ @"와 정확히 동일합니다. bash를 사용하려면 스크립트 파일에서 다음 첫 줄을 사용하십시오. #! / bin / bash
luart

답변:


660

이것을 사용하십시오 :

echo "${@:2}"

다음 구문 :

echo "${*:2}"

로하기 때문에, 잘 작동하지만,하지 않는 것이 좋습니다 @Gordon는 이미 설명, 사용하는 것을 *, 그것은, 공백 하나의 인수로 함께 모든 인수를 실행하는 동안 @보존 그들 사이의 휴식 시간 (심지어 자신에 공백이 포함 된 인수의 몇 가지 경우 ). 와의 차이점은 echo없지만 많은 다른 명령에 중요합니다.


7
방금 Shebang이 나쁘다는 것을 깨달았습니다. #!/usr/bin/env sh그것이 문제가되는 이유입니다. 나는 그 오두막 제거 후 위의 제공과 같이 예는 같은 벌금을, 작동
세타

110
사용 "${@:2}"하는 대신 - 사용 *공간의 단일 인수로 함께 모든 인수의 실행을하는 동안 @보존 그들 사이의 휴식 시간 (인수 중 일부는 자신이 공백을 포함 할 경우에도). 의 차이점은 눈에 띄지 echo않지만 다른 많은 것들에 중요합니다.
Gordon Davisson

2
@GordonDavisson 여기서 요점은 인수를 함께 실행하는 것입니다. 파일 이름을 전달했으면 정확할 것입니다. echo당신을 위해 그들을 연결하기에 충분히 용서하고 있습니다. 다른 명령은 그렇게 좋지 않을 수 있습니다. 둘 중 하나만 사용하지 마십시오.와의 차이점 *@사용시기를 알아 봅니다 . 당신은 그들에 대해 똑같이 사용해야합니다. 이것이 문제가되는 좋은 예 : $3줄 바꿈 ( \n)이 포함 된 경우 기본 $IFS변수 가있는 경우 공백으로 바뀝니다 .
Zenexer

1
@ Zenexer : 제가 이해 한대로, 첫 번째 인수를 제외한 모든 것을 "스크립트의 다른 부분으로"전달하는 방법이 echo예제로 사용되었습니다.이 경우 함께 실행 하면 안됩니다 . 내 경험상, 당신이 그들을 함께 실행하기를 원하는 상황은 드물고 ( 예를 들어이 질문을 보십시오 ) "$@"거의 항상 당신이 원하는 것입니다. 또한 줄 바꿈으로 언급 한 문제 는 $@(또는 $*)이 큰 따옴표가 아닌 경우에만 발생 합니다.
Gordon Davisson

@GordonDavisson 흠 ... 당신이 옳아 요, 지금 생각합니다; 줄 바꿈은 문제가되지 않아야합니다. 나는 다른 것을 생각하고 있었을 것입니다. 그러나 나는 그것들을 함께 운영하는 것에 대해 여전히 동의하지 않아야한다. $*스크립트에서 자주 사용해야 합니다.
Zenexer 12

180

/bin/sh시도해 볼만한 솔루션을 원한다면

first_arg="$1"
shift
echo First argument: "$first_arg"
echo Remaining arguments: "$@"

shift [n]위치 매개 변수를 n 번 이동합니다 . shift세트의 값 $1의 값을 $2, 값 $2의 값과 $3의 값을 감소시키는 등, 그리고, $#하나.


25
+1 : 변수를 옮기기 전에 $ 1을 변수에 저장해야합니다.
glenn jackman

3
놀랍게도 foo=shift내가 기대하는 것을하지 않습니다.
Keith Smiley

나는 이것이 오래 알고 있지만, 시도foo=$(shift)
raumaan kidwai

12
@raumaankidwai 그것은 두 가지 이유로 작동하지 않습니다 : 1) shift(쉘에서) 출력이 없습니다. 그냥 버리고 $1모든 것을 아래로 이동합니다. 2) $(...)자체 지역 인수가있는 서브 쉘을 시작합니다. 그것은 서브 쉘에서 논쟁을 바꾼다. 이것은 부모에게 영향을 미치지 않는다
Ben Jackson

고마워 :)이 방법으로 무엇을 할 수있는 somecommand "$1" "${@:2}"방법이 있습니까?
Anonymous


0

다른 것을 찾고 이걸 발견했습니다. 게시물은 상당히 오래되었지만 bash에서 가장 쉬운 솔루션은 아래에 설명되어 있습니다 (적어도 bash 4). set -- "${@:#}"여기서 #은 앞으로 유지하려는 배열 요소의 시작 번호입니다.

    #!/bin/bash

    someVar="${1}"
    someOtherVar="${2}"
    set -- "${@:3}"
    input=${@}

    [[ "${input[*],,}" == *"someword"* ]] && someNewVar="trigger"

    echo -e "${someVar}\n${someOtherVar}\n${someNewVar}\n\n${@}"

기본적으로 set -- "${@:3}"펄의 교대 와 같이 배열의 처음 두 요소를 터 뜨리고 세 번째 요소를 포함한 나머지 모든 요소를 ​​보존합니다. 마지막 요소도 튀어 나올 수있는 방법이 있다고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.