나는 인용문과 함께 나를 위해 그러한 인수를 생성 할 수있는 스크립트를 작성했습니다.
쉘에 대한 출력이 올바르게 인용 되고 출력을 신뢰하면 실행할 수 있습니다 eval
.
배열을 지원하는 쉘이 있다고 가정하면, 인수를 저장하기 위해 하나를 사용하는 것이 가장 좋습니다.
경우 ./gen_args.sh
출력을 같은 생산 'foo bar' '*' asdf
, 우리는 실행할 수 eval "args=( $(./gen_args.sh) )"
라는 배열 채우는 args
결과와 함께합니다. 즉, 세 가지 요소가 될 것이다 foo bar
, *
, asdf
.
"${args[@]}"
평소처럼 배열 요소를 개별적으로 확장 할 수 있습니다 :
$ eval "args=( $(./gen_args.sh) )"
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
( "${array[@]}"
따옴표는 수정되지 않은 별도의 인수로 모든 요소로 확장됩니다. 따옴표없이 배열 요소는 단어 분할의 대상이됩니다. 예를 들어 BashGuide 의 배열 페이지를 참조하십시오 .)
그러나 , eval
행복하게 때문에, 어떤 쉘 대체를 실행 $HOME
출력의 홈 디렉토리로 확장 것이고, 명령 치환 실제로 쉘 실행에서 명령을 실행하는 것입니다 eval
. 출력은 "$(date >&2)"
하나의 빈 배열 요소를 만들고 stdout에 현재 날짜를 인쇄합니다. gen_args.sh
네트워크를 통한 다른 호스트와 같이 신뢰할 수없는 소스에서 데이터를 가져 오는 경우 다른 사용자가 만든 파일 이름이 문제가됩니다. 출력에는 임의의 명령이 포함될 수 있습니다. ( get_args.sh
자체가 악의적 인 경우 아무 것도 출력 할 필요가 없으며 악의적 인 명령을 직접 실행할 수 있습니다.)
eval없이 구문 분석하기 어려운 쉘 인용의 대안은 스크립트 출력에서 다른 문자를 구분 기호로 사용하는 것입니다. 실제 주장에 필요하지 않은 것을 선택해야합니다.
를 선택 #
하고 스크립트 출력을 갖도록 합시다 foo bar#*#asdf
. 이제 인용되지 않은 명령 확장을 사용 하여 명령의 출력을 인수로 분할 할 수 있습니다 .
$ IFS='#' # split on '#' signs
$ set -f # disable globbing
$ args=( $( ./gen_args3.sh ) ) # assign the values to the array
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
IFS
스크립트의 다른 부분에서 단어 분리에 의존하는 경우 나중에 다시 설정해야하며 ( unset IFS
기본값으로 설정해야 함) set +f
나중에 globbing을 사용하려는 경우 에도 사용해야 합니다.
Bash 또는 배열이있는 다른 쉘을 사용하지 않는 경우 해당 위치 매개 변수를 사용할 수 있습니다. 대신 교체 args=( $(...) )
하여 set -- $(./gen_args.sh)
사용 하십시오 . (여기에도 따옴표가 필요합니다 . 그렇지 않으면 위치 매개 변수에 단어 분할이 적용됩니다.)"$@"
"${args[@]}"
"$@"
eval
사용할 수 있지만 일반적으로 권장하지는 않습니다.xargs
뭔가뿐만 아니라 고려하는 것입니다