次のようなJavaコード内からスクリプトを実行しようとしています。
Process p = Runtime.getRuntime().exec(cmdarray, envp, dir); // cmdarray is a String array
// consisting details of the script and its arguments
final Thread err = new Thread(...); // Start reading error stream
err.start();
final Thread out = new Thread(...); // Start reading output stream
out.start();
p.waitFor();
// Close resources
スクリプトの実行は終了しましたが(pidはもうありません)、JavaはwaitFor()
プロセスのメソッドでスタックしています!。はい、2つの別々のスレッドで出力ストリームとエラーストリームを読み取っています。はい、それらは最後に(後waitFor()
)結合されています。
スクリプトは基本的にいくつかのRPM(10程度など)をインストールし、それらを構成します。したがって、スクリプトは60秒強実行されます。
次のようになります。
#!/bin/sh
#exec 3>&1 >/var/log/some_log 2>&1
# If the above line is uncommented, Java recognizes that the
# process is over and terminates fine.
tar xzf a-package-having-rpms.tar.gz
cd unpacked-folder
(sh installer-script.sh) #This installs 10 odd rpms in a subshell and configures them
cd ..
rm -rf unpacked-folder
exit 0
驚いたことに、スクリプト(上部)に次の行を入れると、Javaはスクリプトが終了したことを認識し、プロセスを完全に終了します。
exec 3>&1 > /var/log/some_log 2>&1
記録のために、スクリプトは出力を生成しません。ゼロ文字!。したがって、execステートメントをそこに置くことは意味がありません!
しかし、それでも、魔法のように、スクリプトにexecステートメントを入れると、Javaが機能します。なぜ??
スクリプトでその非論理的なexecステートメントを回避するにはどうすればよいですか?
Installer-script.shがどのように見えるかに興味がある場合は、次のようにします。
#!/bin/sh
exec 3>&1 >>/var/log/another-log.log 2>&1
INSDIR=$PWD
RPMSDIR=$INSDIR/RPMS
cd $RPMSDIR
#
rpm -i java-3.7.5-1.x86_64.rpm
rpm -i --force perl-3.7.5-1.x86_64.rpm
rpm -i --nodeps mysql-libs-5.0.51a-1.vs.i386.rpm
rpm -i --nodeps mysql-5.0.51a-1.vs.i386.rpm
rpm -i --nodeps mysql-server-5.0.51a-1.vs.i386.rpm
rpm -i --nodeps perl-DBD-MySQL-3.0007-2.el5.i386.rpm
rpm -i --nodeps perl-XML-Parser-2.34-6.1.2.2.1.i386.rpm
.
.
.
では、Javaがプロセスが終了したことを知るために、最初のスクリプトのexecコマンドが必要なのはなぜですか?どうすればその幹部を避けることができますか?、特に。最初のスクリプトは出力を生成しないためです。
息を切らして答えを待っています!