Bash: 명령 대체의 인용문

Bash: 명령 대체의 인용문

즉, 다음 명령으로 나열된 디렉토리를 사용하고 싶습니다 find.

find $(produces_dir_names --options...) -find-options...

문제는 디렉토리 이름에 공백이 있다는 것입니다. 빌드 명령의 출력에서 ​​이를 인용하는 것(변경 가능)이면 충분하다고 생각합니다.

"a" "a b" "a b c"

그러나 bash는 다음과 같이 불평합니다.

find: ‘"a"’: No such file or directory
find: ‘"a’: No such file or directory
find: ‘b"’: No such file or directory
find: ‘"a’: No such file or directory
find: ‘b’: No such file or directory
find: ‘c"’: No such file or directory

보시다시피, bash따옴표를 사용하는 경우에도 공백으로 명령 출력을 분할합니다. 나는 이것저것 만져보고 IFS설정해 보았 \n으나 작동시키기에는 내 이해가 너무 제한적인 것 같습니다.

내가 찾은 유일한 해결책은 이 스택 오버플로 질문에 있습니다. bash 명령 교체 따옴표 제거, 즉 eval앞에 하나를 놓는 것이 좀 보기 흉해 보입니다.

내 질문:

쉬운 방법이 있습니까? 없이 이 대체물을 작성하는 것은 어떤 모습일까요 eval?

견적이 여전히 필요합니까?

예(동일한 출력 생성):

find $(echo '"a" "a b" "a b c"')

답변1

아마도 두 줄로

IFS=$'\n' DIRS=( $(produces_dir_names --options...) ) 
find "${DIRS[@]}" -find-options...

예:

$ mkdir -p "/tmp/test/a b/foo" "/tmp/test/x y/bar"

$ IFS=$'\n' DIRS=( $(printf "/tmp/test/a b\n/tmp/test/x y\n") )
$ find "${DIRS[@]}" -mindepth 1
/tmp/test/a b/foo
/tmp/test/x y/bar

하지만 전반적으로 좋은 스타일은 아닙니다. 예를 들어 DIRS에 개행 문자가 포함되어 있으면 문제가 발생합니다. 널 바이트로 끝나는 문자열을 인쇄하려면 "Produces_dir_names"를 수정하는 것이 좋습니다. 내 예를 들면 다음과 같습니다.

$ printf "/tmp/test/a b\0/tmp/test/x y\0" | xargs -0 -I '{}' find '{}' -mindepth 1
/tmp/test/a b/foo
/tmp/test/x y/bar

내 마지막 의견과 관련하여 "products_dir_names"를 수정할 수 없는 경우 가장 일반적인 해결책은 다음과 같습니다.

produces_dir_names --options... | tr '\n' '\0' | xargs -0  -I '{}' find '{}' -find-options...

"newlines"를 피하기 위해 "Produces_dir_names"를 수정하지 않는 한, "newlines"에 여전히 문제가 있습니다 tr.

답변2

루디 마이어의 답변괜찮습니다. 특히 null로 끝나는 문자열을 인쇄하도록 수정하는 부분입니다 . 하지만 그의 답변에서는 각 디렉토리에 대해 한 번만 수행한다는 produces_dir_names 것이 분명하지 않을 것입니다 . find그 정도라면 괜찮습니다. 그러나 물론 find 다음과 같은 여러 시작점을 사용하여 호출하는 것도 가능합니다.

찾다  디렉토리 1 디렉토리 2 디렉토리 3  -옵션 찾기...

질문에서 이것이 당신이 원하는 것 같습니다. 이 작업은 다음과 같이 수행할 수 있습니다.

printf "a\0a b\0a b c" | printf "a\0a b\0a b c" | xargs -0 sh -c '"$@" 찾기 -옵션 찾기...'다양하다

그러면 모든 디렉터리 이름이 명령에 추가된 단일 xargs호출이 발생합니다. sh -c그런 다음 쉘은 "$@"이러한 디렉토리 이름 목록을 확장합니다.

PS produces_dir_names하나의 명령줄에 들어갈 수 없을 정도로 디렉토리 이름을 너무 많이 나열 하면 xargs일부 명령을 생성해야 합니다. 어떤 명령이 생성되는지 xargs --verbose확인 하는 데 사용됩니다 .xargs

답변3

나타나는 오류 메시지를 이해하기 위해 다음을 수행하십시오.

find: ‘"a"’: No such file or directory
find: ‘"a’: No such file or directory
find: ‘b"’: No such file or directory
find: ‘"a’: No such file or directory
find: ‘b’: No such file or directory
find: ‘c"’: No such file or directory

정답은Bash 인용문 제거는 다음 인용문을 제거하지 않습니다.결과명령 대체에서.

~에서LESS='+/^ *Quote Removal' man bash

Quote Removal
    After the preceding expansions, all unquoted occurrences of the charac-
    ters  \,  ', and " that did not result from one of the above expansions
    are removed.

"위의 확장"에 대한 참조는 다음과 같습니다.

EXPANSION
   Brace Expansion
   Tilde Expansion
   Parameter Expansion
   Command Substitution
   Arithmetic Expansion
   Process Substitution
   Word Splitting
   Pathname Expansion
   Quote Removal

관련 정보