systemdでのダッシュの最大可変長

systemdでのダッシュの最大可変長

KEY=VALUE単一変数を連想配列(1行に1つずつ)として使用するシェルスクリプトがあります。

スクリプトの実行中、変数は項目を追加、削除、または変更するために操作されます。

追加:

VARIABLE="$(printf "%s\n%s" "$VARIABLE" "KEY=VALUE")"

調整:

VARIABLE="$(printf "%s\n" "$VARIABLE" | sed -E "s,^(KEY=).*$,\1VALUE,")"

削除する:

VARIABLE="$(printf "%s\n" "$VARIABLE" | grep -E -v "^KEY=.*$")"

端末で実行されている場合(または以前のシステムのサービスとして)システムinitスクリプトを介して)うまく実行されますが、サービスとして実行されるときシステムしばらくすると、スクリプトはログにエラーメッセージを表示し始めます。

sh: printf: I/O error

多くの試行錯誤の後、スクリプトのどのコマンドがこれらのエラーを生成したのかわかりませんでしたが、変数の長さが8000バイトに達した場合(8192と推測されますが、正確には不明)、まさに私が行全体を追加してからです。

変数の長さが8192バイトに達するたびに、配列内で最も古い項目を切り取るルーチンを実装しているため、変数の長さが問題であると確信しています。スクリプトはsystemdエラーなしで長時間実行されます。一部の情報が失われるため理想的ではありません。

シェルスクリプトの最大変数長に関する情報をオンラインで検索しましたが、有用な情報が見つかりませんでした。

ポータブルで使いたい人はsedスクリプトでは、一部の実装では、行の長さ(パターンと予約済みスペース)を4000バイト以下に制限することが知られています。これPOSIX標準要件は以下に準拠しています。sed実装は少なくとも8192バイトの行長をサポートする必要があります(SHOULD)。GNU sed可能な限り行の長さには基本的な制限はありません。malloc()より多くの(仮想)メモリを使用すると、必要に応じてラインを提供または構築できます。

...しかし、これは次に当てはまります。ワイヤー全文長ではない長さ(1行に80文字以下)

とにかく、エラーはスクリプトが実行されているときにのみ表示されるため、systemdユニットファイルでLimitMSGQUEUEおよび/または増やそうとしましたが、LimitSTACK役に立ちませんでした。 (メッセージキューやプロセススタックの概念を完全に理解していないため、これは盲目的な推測です。ただし、表示された数字はsystemctl show8 KBほどであるようです。メモリ(LimitRSS、、、LimitAS)に関する他のすべての制限はLimitMEMLOCK十分に高いようです。 )次に何をすべきかわかりません。

systemd変数の長さが8KBを超えるときにこのスクリプトを正しく実行するにはどうすればよいですか?

答え1

答えよりは診断に近い…

私のシステムで以下を実行してください。dash v0.5.8-2.10、可変長は少なくともかなり大きくてもよい。2^30性格。${x}文字の長さが薬を超えるまで変数の長さを2倍にするデモです${#x}25%利用可能なメモリ(設定:アドホック furp機能):

最初のスタートdash

dash

次に、dash(で)次のコードを実行します。

furp() { free | { read z; read a b c d; echo $((100*$c/$b)) ; } }
x=1
while [ `furp` -lt 25 ] ; do 
    x="${x}${x}"; echo ${#x}
done | tail -1

出力(私のシステムでは利用可能なメモリによって異なります):

1073741824

上記のコードをスクリプトに入れたら、systemd同じ環境で実行して出力を確認してください。

答え2

(表現力が不足して)

「sh:printf:I / O error」は、スクリプトがsystemdshではなく使用されたことを意味しますdash。おそらくこれはdiffが動作する場所でしょうか?

関連情報