コマンドラインで不均衡な引用符を含むテキストを引数として渡す

コマンドラインで不均衡な引用符を含むテキストを引数として渡す

サードパーティのスケジューラで実行されているジョブのジョブ出力を渡したいです。スケジューラを使用すると、次のコマンドに出力を挿入できます。

python script.py --job-output '{joboutput}'

これは{joboutput}スケジューラが渡した生のジョブ出力になります。

私が経験している問題は、ジョブ出力に不均衡な一重引用符と二重引用符(および特殊文字など)が含まれる可能性があるため、ジョブ出力を一重引用符または(|重引用符で囲むことは機能しないことです。

似たような質問をたくさん見ましたが、この正確なシナリオを扱う質問が見つかりませんでした。どんな提案でもいただきありがとうございます。とても感謝しています!

ベストアンサー1

そのコマンドラインがスケジューラによって前処理され、次に実行のためにシェルに送信された場合(たとえば、)、単純なsh -cテキストを実際のテキストに置き換えた後に{joboutput}要求された内容を実際に実行することはできません。とにかく、一行だけにはありません。

それはい任意の(NUL終了)文字列はコマンドライン引数として渡すことができますが(最大長まで)、シェルコマンドラインに文字列を挿入するには、シェルの構文/引用規則に従う必要があります。

デフォルトでは、シェルには二重引用符、一重引用符、およびバックスラッシュエスケープ機能があります。二重引用符の中には、バックスラッシュの前にいくつかの文字を追加してエスケープする必要があるため、その中に任意の文字列を入れることはできません。一重引用符内では他をエスケープする必要はありませんが、一重引用符自体には特別な処理が必要です。一般的なアプローチは、引用符をに置き換えることです'\''。これは、単に引用符付き文字列を閉じ、エスケープされた一重引用符を挿入して、引用符付き文字列を再度開くことです。それにもかかわらず、一部のキャラクターは特別な扱いが必要であり、これを避ける方法はありません。これは、引用符で囲まれた文字列が終わる位置を決定するためにシェルに何らかの方法が必要であるためです。

"{joboutput}"したがって、 and を含む項目{joboutput}に置き換えると中断され、 and を含む項目に置き換えると中断されます。"$\`'{joboutput}'{joboutput}'

"""一部の言語には、Pythonの/など、もう少し冗長な引用符があります'''。これは時々個々の引用符または引用符のペアを使用することができるので役に立つかもしれませんが、もちろん出力に同じまたはが"""含まれる可能性があるため、それでも完全に普遍的ではありません'''

しかし、殻にはそんなことはありません。最も近いのはおそらくhere-docsであり、自由に選択された項目に分けられます。ワイヤー。これは挿入に役立ちます。ほぼ任意の文字列ですが、複数行を渡すことができなければならず、かなり面倒です。

複数行のコマンドが使用可能な場合は、コマンドの置き換えでhere-docに関連するシェルの解析エラーを禁止しないものに置き換えると{joboutput}機能するはずです。END_OF_JOB_OUTPUTここでは、ドキュメント区切り文字を出力に表示される可能性の低い他の文字列に変更できます。しかし、ここでは、データはコマンド置換を受けるため、データの末尾の改行は失われます。

out=$(cat <<'END_OF_JOB_OUTPUT'
{joboutput}
END_OF_JOB_OUTPUT
)
python script.py --job-output "$out"

または、コマンドの置き換えにこの文書を入れ子にしないでください。

exec 9<<'END_OF_JOB_OUTPUT'
{joboutput}
END_OF_JOB_OUTPUT
out=$(cat <&9)
exec 9<&-

printf "%s\n" "$out"

スケジューラがシェルを使用せずに直接コマンドを実行できる場合は、シェル構文を心配する必要はありません。スケジューラは、ジョブ出力を別の引数に明示的に渡すためのいくつかの賢明な方法が必要script.pyです--job-output。しかし、私たちはそれができることを知りません。 (また、この場合、プレースホルダの周りに引用符を使用しません。)

上記のシェルのハングよりも簡単なもう1つの方法は、環境変数またはファイル(スケジューラがサポートしている場合)を介して文字列を渡すことです。

おすすめ記事