引用する

引用する

これを呼び出すスクリプトがあります

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.

ただし、これはコマンドに含まれる2つのシェル露出ループ(最初のコマンド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 {} \;

関連情報