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

보시다시피 see는 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

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

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

.tr

답변2

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

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

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

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

관련 정보