フィールド分割からIFS文字を「保護」することは可能ですか?

フィールド分割からIFS文字を「保護」することは可能ですか?

POSIX shまたはBourneシェル(Solaris 10のように/bin/sh)で次のようなものを持つことはできますか?

a='some var with spaces and a special space'
printf "%s\n" $a

そしてデフォルトを使用すると、次のような結果がIFS得られます。

some
var
with
spaces
and
a
special space

つまり、引用またはエスケープの組み合わせでspecial間のスペースを保護することです。space

a辞書に単語数がわからない場合は、次のことを試してください。

a='some var with spaces and a special\ space'
printf "%s\n" "$a" | while read field1 field2 ...

文脈はこのエラーCassandraが報告したように、OPはJVMオプションを指定する環境変数を設定しようとしました。

export JVM_EXTRA_OPTS='-XX:OnOutOfMemoryError="echo oh_no"'

Cassandraを実行するスクリプトはPOSIX shとSolaris shをサポートする必要があります。

JVM_OPTS="$JVM_OPTS $JVM_EXTRA_OPTS"
#...
exec $NUMACTL "$JAVA" $JVM_OPTS $cassandra_parms -cp "$CLASSPATH" $props "$class"

IMOの唯一の方法は、コマンドをラップするスクリプトを使用することですecho oh_no。別の方法がありますか?

ベストアンサー1

まさか。

1つの解決策は、文字をフィールド区切り文字として予約することです。当然、そのキャラクターが何でもオプションに含まれる可能性は低いです。ソース言語がタブと改行文字を簡単に挿入できる場合、これは確かな候補です。移植性が必要な場合は、マルチバイト文字を使用しないでください(たとえば、ダッシュとBusyBoxはマルチバイト文字をサポートしていません)。

IFS分割に依存する場合は、ワイルドカード拡張をオフにすることを忘れないでくださいset -f

tab=$(printf '\t')
IFS=$tab
set -f
exec java $JVM_EXTRA_OPTS …

別のアプローチは、参照構文を導入することです。非常に一般的な引用構文は、バックスラッシュを使用して次の文字を保護することです。バックスラッシュの使用の欠点は、さまざまなツールでバックスラッシュを引用符として使用し、時には必要なバックスラッシュの数を決定するのが難しいことです。

set java
eval 'set -- "$@"' $(printf '%s\n' "$JVM_EXTRA_OPTS" | sed -e 's/[^ ]/\\&/g' -e 's/\\\\/\\/g') …
exec "$@"

おすすめ記事