ヘルスサーバーにPOST要求を行い、重要なことについての進捗状況を報告するRed Hat Kickstartプロセスがあります。
%pre
途中で大丈夫ですが、%post
実際のビルドが発生すると情報ブラックホールになります。
進行状況のおおよそのアイデアを提供するために、インストールされているパッケージの数を報告する簡単なシェルフラグメントを作成しました。私は以下を入れました%pre
。
%pre
## various other stuff here, all works fine ##
cat > /tmp/rpm_watcher.sh << EOF_RPM
PREV=-1
while true
do
COUNT="\$(rpm -qa | wc -l)"
if [ \${COUNT} -ne \${PREV} ] ; then
/bin/wget --post-data " ${Hostname} : Package count \${COUNT}" ${builddest}/log
PREV=\${COUNT}
fi
sleep 15
done
EOF_RPM
/bin/sh /tmp/rpm_watcher.sh &
disown -a
%end
ただし、上記からバックグラウンドジョブで起動すると、%pre
スクリプトが完了するのを待たずに%pre
完了しません(生成されたスクリプトを終了すると完了%pre
し、ビルドが正しく開始されます)。
プリインストールされた環境では使用できないため使用できません。nohup
と を使用する場合も同様です。at now
screen
を試してみましたが、disown -a
利用可能です。プロセスは正常に拒否されたようですが(PID 1に属しています)、まだスクリプトが完了するまで停止します。
誰でも私に代替案を提供できますか?
答え1
あなたは解決策に非常に近いです。 Anaconda(インストールプログラム)はPythonで書かれているので、コードを詳しく見ました。
最終的に次のスクリプトを実行します。
rc = iutil.execWithRedirect(self.interp, ["/tmp/%s" % os.path.basename(path)],
stdin = messages, stdout = messages, stderr = messages,
root = scriptRoot)
詳しくは、「iutil.py」で定義されているiutil.execWithRedirectを見つけることができます。この関数は最終的に subprocess.Popen(Python 組み込み) を使用してコマンドを実行します。 %preスクリプトからSTDOUTとSTDERRの内容を取得するのも非常に困難です。
コードは次のとおりです。
#prepare tee proceses
proc_std = tee(pstdout, stdout, program_log.info, command)
proc_err = tee(perrout, stderr, program_log.error, command)
#start monitoring the outputs
proc_std.start()
proc_err.start()
proc = subprocess.Popen([command] + argv, stdin=stdin,
stdout=pstdin,
stderr=perrin,
preexec_fn=chroot, cwd=root,
env=env)
proc.wait()
ret = proc.returncode
#close the input ends of pipes so we get EOF in the tee processes
os.close(pstdin)
os.close(perrin)
#wait for the output to be written and destroy them
proc_std.join()
del proc_std
proc_err.join()
del proc_err
したがって、現在持っているものを使用すると、バックグラウンドに分岐してproc.wait()とos.close呼び出しをバイパスできます。
proc_std と proc_err は繰り返し呼び出されるスレッドです。読書船STDOUTとSTDERRから。 EOFに会うまで読み続けます。スクリプトは%preスクリプトからSTDOUTおよびSTDERRソケットを継承するため、EOFは発生しません。その後、Anacondaは中断され、STDOUTを読み取るスレッドが終了するのを待ちますが( "proc_std.join()"行で)これは決して起こりません。
これは非常に混乱している問題ですが、最終的に非常に簡単な解決策です。変える:
/bin/sh /tmp/rpm_watcher.sh &
使用
/bin/sh /tmp/rpm_watcher.sh > /dev/null 2>&1 < /dev/null &
これにより、スクリプトはSTDOUTとSTDERRを継承しないため、Anacondaが中断されずにインストールを続行できます。
答え2
次のようにスクリプトを背景にする代わりに、スクリプトのwhileループを背景に設定する場合:
while true
do
COUNT="\$(rpm -qa | wc -l)"
if [ \${COUNT} -ne \${PREV} ] ; then
/bin/wget --post-data " ${Hostname} : Package count \${COUNT}" ${builddest}/log
PREV=\${COUNT}
fi
sleep 15
done &
done
ループ行の末尾に「&」記号を追加しましたwhile
。
引用する
答え3
おそらくAnacondaの実装は、提案された解決策を破るために進化したでしょう。私はこのプロセスを決して否定できない。
これでAnaconda環境で利用できるようになりますsystemd
。これは私にとって効果的でした(適応問題)。
cat > /etc/systemd/system/rpm-watcher.service << EOF
[Service]
Type=simple
ExecStart=/bin/sh /tmp/rpm_watcher.sh
EOF
systemctl daemon-reload
systemctl start rpm-watcher
答え4
まあ、時々at now
""で始まるのが私には大丈夫です。
すぐに返され、開始されたプロセスはバックグラウンドで実行されます。
atd
当然走らなければなりません:)
例えば
/bin/echo "/custom/scripte/test.sh" | /usr/bin/at now