この行を置き換えるシェルスクリプトを作成します。
exec "$progdir/$program" ${1+"$@"}
そして:
exec qemu-arm -L /mnt/c/git/build/linux_arm7/build_arm7/sysroot "$progdir/$program" ${1+"$@"}
ファイルから。
/mnt/c/git/build/linux_arm7/build_arm7
という名前の変数にありますBUILD_DIRECTORY
。私が何をしようとしても(引用符、他の区切り文字)、常に置換の代わりに変数で終わります。たとえば、私はこれを試しました:
#!/bin/bash
sed_test()
{
sed -i 's|exec "\$progdir\/\$program" \${1+"\$@"}|exec qemu-arm -L ${BUILD_DIRECTORY}\/sysroot "\$progdir\/\$program" \${1+"\$@"}|g' ${BUILD_DIRECTORY}/file
}
ファイルにこれを得ました:
exec qemu-arm -L ${BUILD_DIRECTORY}/sysroot "$progdir/$program" ${1+"$@"}
これを正しく行う方法は?
答え1
${BUILD_DIRECTORY}
参照により変数の拡張が防止されるg
最終不要- あなたはとても逃げました。
BUILD_DIRECTORY 変数にスペースがない場合は、次のようにします。
sed -i 's|exec "$progdir/$program" ${1+"$@"}|exec qemu-arm -L '${BUILD_DIRECTORY}'/sysroot "$progdir/$program" ${1+"$@"}|' ${BUILD_DIRECTORY}/file
周囲の一重引用符に注意してください。${BUILD_DIRECTORY}
BUILD_DIRECTORYにスペースがある場合(たとえばlinux arm7
)、リレー文字列を使用します(コマンド分割)。
sed -e 's|exec "$progdir/$program" ${1+"$@"}|exec qemu-arm -L BUILD_DIRECTORY/sysroot "$progdir/$program" ${1+"$@"}|'
-e "s|BUILD_DIRECTORY|${BUILD_DIRECTORY}|"
"${BUILD_DIRECTORY}/file"
生産する
exec qemu-arm -L /mnt/c/git/build/linux arm7/build_arm7/sysroot "$progdir/$program" ${1+"$@"}
答え2
そして:zsh
perl
SRC='exec "$progdir/$program" ${1+"$@"}' \
DST='exec qemu-arm -L '${(qq)BUILD_DIRECTORY}' "$progdir/$program" ${1+"$@"}' \
perl -pi -e 's/\Q$ENV{SRC}\E/$ENV{DST}/g' -- "$BUILD_DIRECTORY/file"
Bourneなどのシェルコードを編集しているので、結果が有効なシェルコードであることを確認する必要があります。したがって、、、スペースなどのシェル構文の特殊文字が含まれていても、結果を解析するときにその値が引数として渡されるよう$BUILD_DIRECTORY
に変数の内容を挿入する必要があります。 。sh
qemu-arm
;
?
'
最善の方法は、最も安全な引用モードである一重引用符で表現することです。sh
変数に一重引用符文字が含まれている場合は、\'
一重引用符の外側に挿入してください。これがqq
パラメータ拡張フラグの役割ですzsh
。たとえば、次のようになります。
- 空の文字列を入れます。
''
a;b
入力する'a;b'
a'b
入力する'a'\''b'
$BUID_DIRECTORY
渡されたコード内の値を拡張すると、そのコンテキストで特殊文字をエスケープしない限り、コード注入の脆弱性が発生することを意味しますsed
。sed
また、-i
(sed
参照からコピーしたいくつかの実装perl
)は標準ではありません。
代わりに使用することは、perl
次のことを意味します。
-i
ポータブルで使用できます- /を
$SRC
使用してエスケープできるため、正規表現演算子をエスケープする必要はありません。\Q
\E
- 代替を避ける必要はありません。
答え3
sedコードを挿入するために変数を使用する方法は、s///
コマンドのLHSまたはRHSで使用されているかどうかに応じて、最初にシェル検証可能なコンテンツをエスケープすることです。
& \ and :
あなたのシナリオでは、ビルド変数がrhsに配置されます。したがって、実際のsedコードは区切り文字として使用されるため、文字をエスケープする必要がありますs:::
。また、ビルド変数が複数行の場合、改行もエスケープされます。変数は一重引用符で囲まれているため、'\''
ビルド変数に一重引用符がある場合は、すべての一重引用符も変更する必要があります。
BUILD_DIRECTORY='/mnt/c/git/build/linux_arm7/build_arm7'
BUILD_DIRECTORY_rhs=$(printf '%s\n' "${BUILD_DIRECTORY}" |
sed \
-e 's/[\&:]/\\&/g' \
-e 's/'\''/&\\\\&&/g' \
-e '$!s/$/\\/')
sed -i -e 's:^exec \("$progdir/$program" ${1+"$@"}\)$:'"exec qemu-arm -L '${BUILD_DIRECTORY_rhs}/sysroot' \\1:" -- "${BUILD_DIRECTORY}/file"
この出力は次のようになります。
exec qemu-arm -L '/mnt/c/git/build/linux_arm7/build_arm7/sysroot' "$progdir/$program" ${1+"$@"}