![쉘 스크립트에서 인용된 인수 목록 문자열을 올바르게 구문 분석하는 방법은 무엇입니까?](https://linux55.com/image/198407/%EC%89%98%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%97%90%EC%84%9C%20%EC%9D%B8%EC%9A%A9%EB%90%9C%20%EC%9D%B8%EC%88%98%20%EB%AA%A9%EB%A1%9D%20%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84%20%EC%98%AC%EB%B0%94%EB%A5%B4%EA%B2%8C%20%EA%B5%AC%EB%AC%B8%20%EB%B6%84%EC%84%9D%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
일반화하다
a "b" 'c d' $'e\nf'
따옴표를 존중하고 공백과 개행 문자를 유지하면서 단일 문자열을 별도의 매개변수로 변환하는 방법은 무엇입니까 ?
질문
값 목록(한 줄에 하나씩)을 따옴표 붙은 문자열(에서 생성)로 내보내는 스크립트의 출력을 읽고 처리하려고 합니다 printf %q
. 목록의 값은 공백으로 구분되고, 따옴표로 묶을 수 있으며, 공백과 줄 바꿈을 포함할 수 있으며 개수를 알 수 없습니다.
예:a "b" 'c d' $'e\nf'
POSIX 쉘 스크립트에서 값을 복원하고 이를 쉘 함수에 대한 인수로 처리하는 방법을 찾고 있습니다.
필요한 솔루션(우선순위 내림차순):
- POSIX 쉘 명령 및 핵심 유틸리티
xargs
등printf
eval
- 불다
- Perl과 같은 성숙한 프로그래밍 언어
쉘 스크립트의 뼈대 process.sh
:
#!/bin/sh
set -eu
process() {
printf '>%s<\n' "${@}"
}
main() {
value_list="${1}"
# split value list here and set positional parameters
set -- ???
process "${@}"
}
main "${@}"
원하는 행동
$ process.sh "a \"b\" 'c d' $'e\nf'"
>a<
>b<
>c d<
>e
f<
지금까지 무슨 일이 있었나요
printf
나는 (포함%q
),xargs
루프while read
, 변경IFS
, 바이트 구분 인수null
, 서브쉘 호출, heredocs 의 다양한 조합을 시도했습니다 .xargs
역참조는 허용되지만 공백에 대해서만 가능하고 개행 문자에는 허용되지 않으며 인수 없이만 허용됩니다-d
.- 루프는
while read
인수를 구문 분석할 수 있지만 파이프에서 입력을 읽는 동안 셸 함수를 호출하는 것은 허용되지 않습니다.
답변1
이 답변은 다음을 기반으로 합니다.논평통과이르카초을 사용하고 zsh
.
쉘 스크립트 process.sh
:
#!/bin/sh
set -eu
export script="$(readlink -f "${0}")"
split() {
zsh -c 'printf "%s\0" "${(Q@)${(z)1}}"' "${script}/split" "${@}"
}
process() {
printf '>%s<\n' "${@}"
}
main() {
value_list="${1}"
split "${value_list}" | xargs -0 sh -c 'init() { . "${script}"; } && init && process "${@}"' "${script}/main"
}
[ "${#}" -eq 0 ] || main "${@}"
혜택
- 효과가있다
결점
- 매개변수를 제거하고 무한 루프를 방지하기 위해
process()
양식을 호출하는 스크립트를 함수로 래핑해야 하는 것은 약간 어색합니다.xargs
- 필요하다
zsh
답변2
단순화된 변형이것 zsh
다음을 기준으로 답변하세요.
#!/bin/zsh
set -eu
process() {
printf '>%s<\n' "${@}"
}
main() {
value_list="${1}"
process "${(Q@)${(z)value_list}}"
}
main "${@}"
혜택
- 효과가있다
결점
- zsh 요구 사항