인용하다

인용하다

이것을 호출하는 스크립트가 있습니다

find "/mnt/Data/Shared/$1" -type d -exec bash -c 'fixperm "'${1}'" "fd" "$0"' {} \;

$1은 디렉토리입니다. 이름에 공백이 없으면 작동하지만, 공백이 있으면 실패하고 오류를 반환합니다. "00_Office Test"를 사용하여 테스트

Test" "fd" "$0": -c: line 0: unexpected EOF while looking for matching `"'
Test" "fd" "$0": -c: line 1: syntax error: unexpected end of file

경로에 공백 앞에 \가 없기 때문에 그럴 수도 있다고 생각했지만 문제가 해결되지 않았습니다. 나는 여기서 사소한 것을 놓치고 있다고 확신합니다.

답변1

이는 작은따옴표 밖에 나타나기 때문입니다 ${1}. 즉, 쉘이 보기 전에 확장되고 토큰화된다는 의미입니다 find. StackExchange의 구문 강조 표시를 통해 이를 명확하게 알 수 있습니다. 단어 분리를 방지하려면 큰따옴표를 사용하세요.

또한 호출을 사용하면 bash -c따옴표를 직접 처리해야 하지만 파일 이름에 큰따옴표가 포함되어 있으면 문제가 발생할 수 있습니다. 사용하지 말고 매개변수를 직접 전달하세요.

find "/mnt/Data/Shared/$1" -type d -exec fixperm "$1" fd {} \;

답변2

따옴표 없이 사용하고 있기 때문입니다 ${1}.

인용하다

견적 문제를 해결하는 것은 상당히 복잡할 수 있습니다.

'${1}'으로 바꾸는 것이 '"${1}"'도움이 될 것 같습니다.

비교하다:

$ set -- "ab cd"; bash -c 'printf "<%s> " '${1}' "fd" "$0"'
<ab>

그리고:

$ set -- "ab cd"; bash -c 'printf "<%s> " '"${1}"' "fd" "$0"'
<ab> <cd> <fd> <bash>

그러나 쉘 "인용 제거"는 여전히 변수 값에 적용됩니다.
해결 방법으로 다음을 사용할 수 있습니다.'"${1@Q}"'

$ set -- 'a"b c"d'; bash -c 'printf "<%s> " '"${1}"' "fd" "$0"'; echo
<ab cd> <fd> <bash>               # quotes got lost.

$ set -- 'a"bc"d'; bash -c 'printf "<%s> " '"${1@Q}"' "fd" "$0"'; echo
<a"b c"d> <fd> <bash>             # correct quotes.

그러나 이는 명령에 포함된 두 개의 셸 노출 루프(먼저 명령 find, 다음 bash -c명령)에서는 작동하지 않습니다.

$ mkdir 'a"bc"d' 'a"b c"d' 'a"bcd'

$ set -- 'a"bc"d'; find "./$1" -type d -exec bash -c 'printf "<%s> " fixperm "'"${1}"'" "fd" "$0"' {} >
<fixperm> <abcd> <fd> <./a"b c"d>

$ set -- 'a"b c"d'; find "./$1" -type d -exec bash -c 'printf "<%s> " fixperm "'"${1}"'" "fd" "$0"' {} >
<fixperm> <ab> <cd> <fd> <./a"b c"d>

$ set -- 'a"bcd'; find "./$1" -type d -exec bash -c 'printf "<%s> " fixperm "'"${1}"'" "fd" "$0"' {} \; 
./a"bcd: -c: line 0: unexpected EOF while looking for matching `"'
./a"bcd: -c: line 1: syntax error: unexpected end of file

옳은

$1그러나 실제로 일어나는 일은 $1호출하는 스크립트의 매개변수와 호출하는 쉘의 의미 사이에 혼동이 있는 것 같습니다.bash -c

은행:

find "/mnt/Data/Shared/$1" -type d -exec bash -c '
     fixperm "'"${1}"'" "fd" "$0"' {} \;

읽어야합니다:

find "/mnt/Data/Shared/$1" -type d -exec bash -c '
     fixperm "$1" "fd" "$2"' bash-shell "$1" {} \;

이는 인용을 더욱 직접적이고 강력하게 만듭니다.

단순한

스크립트 내에서 실행할 루프나 기타 복잡한 기능이 없으면 bash -c거의 모든 참조를 제거하고 작성할 수 있습니다.

dir="/mnt/Data/Shared"

find "$dir/$1" -type d -exec fixperm "$1" fd {} \;

관련 정보