Bash 셸 스크립트의 모든 인수 전파
다른 스크립트를 호출하는 매우 간단한 스크립트를 작성하고 있으며 현재 스크립트에서 실행 중인 스크립트로 파라미터를 전파해야 합니다.
예를 들어, 제 스크립트 이름은foo.sh
및 콜bar.sh
.
foo.sh:
bar $1 $2 $3 $4
각 파라미터를 명시적으로 지정하지 않고 어떻게 하면 좋을까요?
사용하다"$@"
평범하지 않고$@
파라미터가 동일하게 전달되기를 원하는 경우.
다음 사항을 확인합니다.
$ cat no_quotes.sh
#!/bin/bash
echo_args.sh $@
$ cat quotes.sh
#!/bin/bash
echo_args.sh "$@"
$ cat echo_args.sh
#!/bin/bash
echo Received: $1
echo Received: $2
echo Received: $3
echo Received: $4
$ ./no_quotes.sh first second
Received: first
Received: second
Received:
Received:
$ ./no_quotes.sh "one quoted arg"
Received: one
Received: quoted
Received: arg
Received:
$ ./quotes.sh first second
Received: first
Received: second
Received:
Received:
$ ./quotes.sh "one quoted arg"
Received: one quoted arg
Received:
Received:
Received:
bash 및 기타 Bourne 유사 쉘의 경우:
bar "$@"
사용하다"$@"
(모든 POSIX 호환성이 있습니다).
[...] , bash에는 공백으로 구분된 모든 명령줄 파라미터로 확장되는 "$@" 변수가 있습니다.
예를 들어 Bash에서.
이 질문에 대한 답변이 적절하다는 것은 알지만, "$@" $@ "$*"와 "$*"의 비교는 다음과 같습니다.
테스트 스크립트의 내용:
# cat ./test.sh
#!/usr/bin/env bash
echo "================================="
echo "Quoted DOLLAR-AT"
for ARG in "$@"; do
echo $ARG
done
echo "================================="
echo "NOT Quoted DOLLAR-AT"
for ARG in $@; do
echo $ARG
done
echo "================================="
echo "Quoted DOLLAR-STAR"
for ARG in "$*"; do
echo $ARG
done
echo "================================="
echo "NOT Quoted DOLLAR-STAR"
for ARG in $*; do
echo $ARG
done
echo "================================="
이제 다양한 인수를 사용하여 테스트스크립트를 실행합니다.
# ./test.sh "arg with space one" "arg2" arg3
=================================
Quoted DOLLAR-AT
arg with space one
arg2
arg3
=================================
NOT Quoted DOLLAR-AT
arg
with
space
one
arg2
arg3
=================================
Quoted DOLLAR-STAR
arg with space one arg2 arg3
=================================
NOT Quoted DOLLAR-STAR
arg
with
space
one
arg2
arg3
=================================
여기에 많은 답변이 권장됩니다.$@
또는$*
인용구가 있든 없든, 그러나 이것이 실제로 무엇을 하는지, 왜 그렇게 해야 하는지를 설명하는 사람은 아무도 없는 것 같습니다.이 답변에서 이 훌륭한 요약을 인용하겠습니다.
+--------+---------------------------+
| Syntax | Effective result |
+--------+---------------------------+
| $* | $1 $2 $3 ... ${N} |
+--------+---------------------------+
| $@ | $1 $2 $3 ... ${N} |
+--------+---------------------------+
| "$*" | "$1c$2c$3c...c${N}" |
+--------+---------------------------+
| "$@" | "$1" "$2" "$3" ... "${N}" |
+--------+---------------------------+
따옴표는 모든 차이를 가져오며 따옴표가 없으면 둘 다 동일한 동작을 합니다.
이 때문에 어떤 스크립트에서 다른 스크립트로 파라미터를 전달할 필요가 있었습니다.이를 위해 최적의 옵션은 다음과 같습니다.
# file: parent.sh
# we have some params passed to parent.sh
# which we will like to pass on to child.sh as-is
./child.sh $*
따옴표는 없습니다.$@
위의 상황에서도 동작합니다.
#!/usr/bin/env bash
while [ "$1" != "" ]; do
echo "Received: ${1}" && shift;
done;
스크립트에 arg가 어떻게 들어가는지 테스트할 때 이 방법이 좀 더 유용할 것 같아서요.
다음을 포함하면$@
따옴표로 묶인 문자열에서 여러 개의 인수가 있을 경우 동작이 매우 이상하며 첫 번째 인수만 따옴표 안에 포함됩니다.
예:
#!/bin/bash
set -x
bash -c "true foo $@"
수율:
$ bash test.sh bar baz
+ bash -c 'true foo bar' baz
그러나 먼저 다른 변수에 할당:
#!/bin/bash
set -x
args="$@"
bash -c "true foo $args"
수율:
$ bash test.sh bar baz
+ args='bar baz'
+ bash -c 'true foo bar baz'
내 SUN Unix에는 많은 제한이 있습니다. $@도 원하는 대로 해석되지 않았습니다.회피책은 ${@}입니다.예를들면,
#!/bin/ksh
find ./ -type f | xargs grep "${@}"
덧붙여서, 이 스크립트는 UNIX에서도 grep-r을 지원하지 않기 때문에 필요했습니다.
모든 인수를 통과시키고 싶지만 앞에 플래그(예: 플래그)가 붙는 경우가 있습니다.--flag
)
$ bar --flag "$1" --flag "$2" --flag "$3"
이 작업은 다음과 같은 방법으로 수행할 수 있습니다.
$ bar $(printf -- ' --flag "%s"' "$@")
참고: 추가 필드 분할을 방지하려면 따옴표를 작성해야 합니다.%s
그리고.$@
단일 문자열을 사용하지 않도록 하기 위해 서브셸을 따옴표로 묶을 수 없습니다.printf
.
bar "$@"
상당합니다.bar "$1" "$2" "$3" "$4"
따옴표는 중요합니다!
"$@"
,$@
,"$*"
★★★★★★★★★★★★★★★★★」$*
는, 이 스택 오버 플로우 응답에 기재되어 있듯이, 이스케이프 및 접속에 관해서 각각 약간 다른 동작을 합니다.
이와 밀접하게 관련된 한 가지 사용 사례는 다음과 같은 인수 내에 지정된 모든 인수를 전달하는 것입니다.
bash -c "bar \"$1\" \"$2\" \"$3\" \"$4\""
.
이를 달성하기 위해 @kvantour의 답변을 변형하여 사용합니다.
bash -c "bar $(printf -- '"%s" ' "$@")"
공백이나 이스케이프 문자를 제외하고 정상적으로 동작합니다.이 경우 인수를 캡처하여 스크립트 내의 SSH로 전송하는 방법을 찾을 수 없습니다.
이것은 유용할 수 있지만 너무 못생겼다.
_command_opts=$( echo "$@" | awk -F\- 'BEGIN { OFS=" -" } { for (i=2;i<=NF;i++) { gsub(/^[a-z] /,"&@",$i) ; gsub(/ $/,"",$i );gsub (/$/,"@",$i) }; print $0 }' | tr '@' \' )
"${array[@]}"
는 bash에서 어레이를 전달하기 위한 올바른 방법입니다.저는 완전한 치트 시트를 제공하고 싶습니다.논쟁을 준비하고, 회피하고, 처리하는 방법.
pre.sh
->foo.sh
->bar.sh
.
#!/bin/bash
args=("--a=b c" "--e=f g")
args+=("--q=w e" "--a=s \"'d'\"")
./foo.sh "${args[@]}"
#!/bin/bash
./bar.sh "$@"
#!/bin/bash
echo $1
echo $2
echo $3
echo $4
결과:
--a=b c
--e=f g
--q=w e
--a=s "'d'"
언급URL : https://stackoverflow.com/questions/3190818/pass-all-arguments-from-bash-script-to-another-command
'programing' 카테고리의 다른 글
Azure Service Fabric은 Docker와 같은 기능을 합니까? (0) | 2023.04.23 |
---|---|
Objective-C의 isEqualToString과 동등한 Swift는 무엇입니까? (0) | 2023.04.23 |
PowerShell: 명령어 출력 방법 (0) | 2023.04.23 |
iOS 및 WatchKit에서 이미지 tintColor를 변경하는 방법 (0) | 2023.04.23 |
UITableView의 셀 하이라이트 색상을 삭제합니다. (0) | 2023.04.23 |