パラメータが長すぎる問題を解決する方法

パラメータが長すぎる問題を解決する方法

私はシェルスクリプトに初めて触れました。動的HTMLコンテンツを作成し、そのコンテンツを変数に割り当て、この変数の値を使用してシェル(Linux)内のテンプレートを置き換える必要がある既存のシェルスクリプトを変更しています。

以下のコードスニペットを使用していますが、HTMLコンテンツが少ない場合は正常に機能しますが、コンテンツが大きいと同じように失敗します。この問題を解決する方法。

encStr="$(cat ./dynamiccontent.html | base64)"
echo $encStr
awk -v var="$encStr" '{gsub("REPLACECONTENT", var, $0); print}' /path/tomytemplate > output.tmp

ベストアンサー1

@mosvyはすでに素晴らしい答えを与えてくれました。

物語の簡単な教訓は次のとおりです。検証されていない長さのデータを格納するためにシェル変数を使用するのは良い考えではありません。通常、シェル変数やシェルを使用することはプログラミング言語を混乱させるので、まったく良い考えではありません。ただし、シェル変数に何かを保存する必要がある場合は、次のようなクレイジーをステップバイステップで試してみることもできます。

プロセスの置き換えにより、すべての内容を含む一時ファイルを作成します。実際、シェル組み込み機能には一般的なサブプロセスパラメータ制限は適用されません。

awk -v patternFile=<( printf "$encStr" )

AWKを使用する退屈な方法(最終的には通常は行指向のUnixツールです)、一時ファイル全体をAWK変数 "contents"として読み、最初にそれを行に分割してから文字列連結を使用して再構築し、任意の項目を追加します。する退屈な方法です。改行は分割で削除されます。

awk -v substitutionFile=<( printf "$encStr" ) 'BEGIN {while ((getline line <substitutionFile) > 0) { contents = contents line "\n"}}'

次に、テンプレートファイルで置き換えるタグを決定するためにすでに使用していた通常の行中心の方法で置換を実行します。

awk -v substitutionFile=<( printf "$encStr" ) 'BEGIN {while ((getline line <substitutionFile) > 0) { substitutionString = substitutionString line "\n"}} {gsub("REPLACECONTENT", substitutionString, $0); print}' /path/tomytemplate > output.tmp

今、上記の解決策は見苦しいです...しかし、* nixシェル標準では十分に見苦しくありません!すでに *nix シェルを使用している場合は、heredoc を使用するとどうなりますか?これにより、printfコマンドが関数にオーバーライドされるリスクが軽減されますが(私のシステムでは、本番コードでは失敗します:D)、heredoc区切り文字を含むファイルのリスクが高くなります。

awk -v substitutionFile=<( cat <<HOPEFULLY_UNIQUE_HEREDOC_DELIMITER
$encStr
HOPEFULLY_UNIQUE_HEREDOC_DELIMITER
) 'BEGIN {while ((getline line <substitutionFile) > 0) { substitutionString = substitutionString line "\n"}} {gsub("REPLACECONTENT", substitutionString, $0); print}' /path/tomytemplate > output.tmp

区切り文書の変数置換は引用符で計算されるため、quoteを使用しないでください$encStr。それ以外の場合は、代替文字列にも引用符が含まれます。これはシェル置換の規則 1749203 です。他の場合の主なルールは簡単です。変数とコマンドの置換に二重引用符を使用しないと死にます。

この場合、cat組み込みファイルではないことは重要ではありません。これは、標準入力をheredocによって生成された一時ファイルにリダイレクトするためです。このファイル自体にはパラメータ渡しが含まれていないため、長さ制限はありません。

おすすめ記事