bash/ash 함수에 전달된 인수는 어떻게 되나요?

bash/ash 함수에 전달된 인수는 어떻게 되나요?

이 답변은 ---POSIX 셸 사용에 대한 유용한 정보를 많이 제공합니다.모든 매개변수를 스크립트에 전달하는 방법에 대한 답변입니다.그 결과 다음과 같은 기능이 발생합니다.

my_echo()
{
    set -x
    echo $@ " " \"$@\"
    echo `ps | grep -- "$@" | grep -v grep | awk '{ print $1 }'` 2>/dev/null
    set +x
}

my_echo logread -f

저는 OpenWRT용으로 이 스크립트를 작성하고 있습니다. 재 출력 쇼

+ echo logread -f   "logread -f"
logread -f   "logread -f"
+ ps
+ grep -v grep
+ awk { print $1 }
+ grep -- logread -f
grep: -f: No such file or directory
+ echo

+ set +x

흠... grep 명령에 추가한 따옴표가 사라졌습니다(logread -f 따옴표가 없음).

Bash에서 이 기능을 사용해 보았습니다.

+ echo logread -f ' ' '"logread' '-f"'
logread -f   "logread -f"
++ ps
++ grep --color=auto -- logread -f
++ grep --color=auto -v grep
++ awk '{ print $1 }'
grep: -f: No such file or directory
+ echo

+ set +x

흥미롭네요... 아마도 제 주장이 개별적으로 분석되고 있는 것 아닐까요? 이 이론을 테스트하기 위해 나는 다음을 시도했습니다.

my_echo "logread -f"

큰 타격 출력:

+ echo logread -f ' ' '"logread' '-f"'
logread -f   "logread -f"
++ ps
++ grep --color=auto -- 'logread -f'
++ grep --color=auto -v grep
++ awk '{ print $1 }'
+ echo

+ set +x

echo 명령의 출력은 변경되지 않았습니다(버전 set이나 실제 출력이지만 logread -f지금은 큰따옴표로 묶인 것으로 처리되는 것 같습니다. 그래서... set명령의 번역을 잘못 이해했기 때문에 운이 좋았습니다. 그러나 이제 내 기능이 작동합니다. .

재 출력:

+ echo logread -f   "logread -f"
logread -f   "logread -f"
+ ps
+ grep -v grep
+ awk { print $1 }
+ grep -- logread -f
+ echo

+ set +x

이제 나는 내가 기대했던 것을 얻습니다. 큰따옴표(단일 인수)로 전달된 인수를 사용 하면 my_echo다음과 동일하게 실행됩니다.

my_echo_new()
{
    echo `ps | grep -- "$1" | grep -v grep | awk '{ print $1 }'` 2>/dev/null
}

my_echo_new "logread -f"

그래서... 문제는 여러 매개변수를 다루는 것 같습니다. 여기서 무슨 일이 일어나고 있는 걸까요? 이것은 `의 결과입니까, 아니면 함수 호출의 결과입니까, 아니면 다른 것입니까? 두 위치 모두에 큰따옴표가 필요한 이유는 무엇입니까?

답변1

"$@"다음으로 확장목록따옴표 붙은 문자열. 두 개의 인수 logread-f함수에 전달하면 "$@"다음과 같이 확장 됩니다.끈.

따라서 실행 중은 grep -- "$@"으로 확장됩니다 grep -- logread -f. 이는 " logread이름이 지정된 파일에서 grep for" 를 의미합니다 -f.

"$*"단일 문자열 대신 별도의 매개변수를 전달한 다음 매개변수를 작은따옴표로 묶은 문자열로 확장 하시겠습니까 ?

grep -e "$*"

사용하면 위치 인수가 첫 번째 문자로 구분됩니다 grep -e "logread -f"( 기본적 으로 공백임). 또한 또는$IFS"$*"$*$@ 인용되지 않음무의미한.

pgrep그런데 여기서 /를 사용하도록 선택할 수도 있습니다 pkill.

if ! pgrep -xf "$*" >/dev/null; then
    printf 'No process matches "%s" exactly\n' "$*"
fi

관련 정보