함수 내에서 호출자의 명령 줄 인수에 액세스하는 방법은 무엇입니까?


95

스크립트 명령 줄 인수에 액세스하는 bash에서 함수를 작성하려고하지만 함수에 대한 위치 인수로 대체됩니다. 명시 적으로 전달되지 않은 경우 함수가 명령 줄 인수에 액세스 할 수있는 방법이 있습니까?

# Demo function
function stuff {
  echo $0 $*
}

# Echo's the name of the script, but no command line arguments
stuff

# Echo's everything I want, but trying to avoid
stuff $*

3
나는 약간 혼란 스럽습니다. 당신은 그들을 전달하지 않고 논쟁을 원합니까?
Ravi Vyas

4
예, 요점은 기능적 인수로 전달하지 않고 함수 내부에서 명령 줄 인수를 너무 가져 오는 것입니다. 함수에 전달 된 인수와 독립적으로 명령 줄 인수를 기반으로 오류 처리를 수행하려는 오류 처리 상황과 관련이 있습니다.
DonGar

참고로, $*매우 버그 - 그것은 변경할 수 있습니다 ./yourScript "first argument" "second argument"./yourscript "first" "argument" "second" "argument", 또는 변경 ./yourscript '*.txt'과 같은 뭔가를 ./yourscript one.txt two.txt따옴표에도 불구하고.
Charles Duffy

답변:


46

bash ref 매뉴얼을 읽었을 때 "스택"에 대해 많이 언급하지만 BASH_ARGV에이 내용이 캡처되었다고합니다.

#!/bin/bash

function argv {
    for a in ${BASH_ARGV[*]} ; do
      echo -n "$a "
    done
    echo
}

function f {
    echo f $1 $2 $3
    echo -n f ; argv
}

function g {
    echo g $1 $2 $3
    echo -n g; argv
    f
}

f boo bar baz
g goo gar gaz

f.sh에 저장

$ ./f.sh arg0 arg1 arg2
f boo bar baz
farg2 arg1 arg0 
g goo gar gaz
garg2 arg1 arg0 
f
farg2 arg1 arg0 

5
그렇게 배열을 itterating하면 명령 줄에서 인수가 역순으로 표시됩니다.
Andrew Backer 2011

93

인수 C 스타일 (인수 배열 + 인수 수)을 사용하려면 $@및 을 사용할 수 있습니다 $#.

$#인수의 수를 제공합니다.
$@당신에게 모든 논쟁을 제공합니다. 을 사용하여 이것을 배열로 바꿀 수 있습니다 args=("$@").

예를 들면 다음과 같습니다.

args=("$@")
echo $# arguments passed
echo ${args[0]} ${args[1]} ${args[2]}

여기에 ${args[0]}실제로 스크립트의 이름이 아니라 첫 번째 인수가 있습니다.


5
이것은 질문을 해결하지 않습니다. 명령 줄 인수를 셸 함수에 전달하는 것에 대해 묻는 것입니다.
Cascabel

6
@Jefromi, 실제로 질문에 완벽하게 대답합니다. args설명대로 미리 초기화하면 함수 내부 에서 배열을 사용할 수 있습니다 .
vadipp 2013

1
나는 args를 반복하는 것보다 훨씬 더 깨끗하다는 것을 알았습니다.
Félix Gagnon-Grenier

1
이것은 간단하고 쉽습니다. 좋은 대답입니다. 이 글을 7 년 전에 게시 했으므로 미래에서 안녕하세요 : 2017 년 7 월
SDsolar

더 나은 따옴표 echo "${args[0]} ${args[1]} ${args[2]}"를 사용하거나 인수가 파일 이름 확장에 따라 달라집니다.
Benjamin W.

17
#!/usr/bin/env bash

echo name of script is $0
echo first argument is $1
echo second argument is $2
echo seventeenth argument is $17
echo number of arguments is $#

편집 : 질문에 대한 내 의견을 참조하십시오


16

Ravi의 의견은 본질적으로 답입니다. 함수는 자체 인수를 사용합니다. 명령 줄 인수와 동일하게하려면 반드시 전달해야합니다. 그렇지 않으면 인수없이 함수를 명확하게 호출하는 것입니다.

즉, 명령 줄 인수를 전역 배열에 저장하여 다른 함수 내에서 사용할 수 있습니다.

my_function() {
    echo "stored arguments:"
    for arg in "${commandline_args[@]}"; do
        echo "    $arg"
    done
}

commandline_args=("$@")

my_function

당신은을 통해 명령 줄 인수에 액세스 할 수있는 commandline_args변수가 아닌 $@, $1, $2, 등,하지만 그들은 사용할 수있어. 인수 배열에 직접 할당하는 방법을 알지 못하지만 누군가가 아는 경우 저를 계몽하십시오!

또한 내가 사용하고 인용 한 방식에 유의하십시오. $@이것이 특수 문자 (공백)가 엉망이되지 않도록하는 방법입니다.


6
# Save the script arguments
SCRIPT_NAME=$0
ARG_1=$1
ARGS_ALL=$*

function stuff {
  # use script args via the variables you saved
  # or the function args via $
  echo $0 $*
} 


# Call the function with arguments
stuff 1 2 3 4

2

이렇게도 할 수 있어요

#!/bin/bash
# script_name function_test.sh
function argument(){
for i in $@;do
    echo $i
done;
}
argument $@

이제 스크립트를 다음과 같이 호출하십시오.

./function_test.sh argument1 argument2

function print() {두 개의 서로 다른 함수 선언 형식- function print {, bash가 이전 POSIX (즉, 1991 년 이전) ksh와의 하위 호환성을 지원하는 레거시 ksh 구문 및 print() {POSIX 표준화 된. 다른 쉘과의 호환성을 높이려면 둘 중 하나를 사용하는 것이 좋습니다. wiki.bash-hackers.org/scripting/obsolete
Charles Duffy

1

시프트 키워드 (연산자?)를 사용하여 반복 할 수 있습니다. 예:

#!/bin/bash
function print()
{
    while [ $# -gt 0 ]
    do
        echo $1;
        shift 1;
    done
}
print $*;

2
function print() {두 개의 서로 다른 함수 선언 형식- function print {, bash가 이전 POSIX (즉, 1991 년 이전) ksh와의 하위 호환성을 지원하는 레거시 ksh 구문 및 print() {POSIX 표준화 된. 다른 쉘과의 호환성을 높이려면 둘 중 하나를 사용하는 것이 좋습니다. wiki.bash-hackers.org/scripting/obsolete
Charles Duffy

1

내 솔루션 :

인수를 전달하지 않고 다른 모든 함수보다 먼저 호출되는 함수 스크립트를 다음과 같이 만듭니다.

! / bin / bash

function init () {ORIGOPT = "-$ @-"}

따라서 init를 호출하고 필요에 따라 ORIGOPT var를 사용할 수 있습니다. 플러스로 항상 새 var를 할당하고 새 함수에 ORIGOPT의 내용을 복사합니다. 이렇게하면 아무도 만지지 않을 것임을 확신 할 수 있습니다. 그것을 바꾸십시오.

'sed -E'로 쉽게 구문 분석 할 수 있도록 공백과 대시를 추가했습니다. 또한 bash는이를 참조로 전달하지 않고 함수가 더 많은 인수로 호출됨에 따라 ORIGOPT가 커지도록합니다.

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