1

次の簡単なスクリプト (test.sh) があります。

    #!/bin/bash
    tail -f /var/log/dmesg > /tmp/output.log &
    echo "THE END"
    exit 0

この test.sh スクリプトを Java プログラムから (リモートで ssh の下で) 呼び出した後、Java コンソール (Eclipse) はロックされたままになります。次に、1)サーバーで「tail -f /var/log/dmesg > /tmp/output.log」プロセスを手動で強制終了すると、コンソールのロックが解除され、コンソールに「THE END」メッセージが表示されます。2) スクリプトから「tail -f /var/log/dmesg > /tmp/output.log」を削除して Java アプリを実行すると、ロックが発生せず、コンソールに「THE END」メッセージが表示されます。

test.sh を介して bg で tail -f を実行し、Java アプリケーション フローを続行する人はいますか?

4

3 に答える 3

0

htisの記事をご覧ください。これは、プロセスでの作業中の主な間違いについて説明しています。あなたがしなければならないのは、Steam Gobbler(入力ストリームのコンシューマー)を追加することです。これにより、バッファーがいっぱいになったために、出力への書き込み中に外部プログラムがスタックしないようになります。

于 2013-03-10T07:29:23.713 に答える
0

Java 経由で Unix システム コマンドを実行する場合、Java 側にもいくつかの落とし穴がある場合があります。たとえば、Unix ベースのオペレーティング システムの標準 I/O ストリーム (stdout、stderr、stdin) が Java スレッドで読み取られていない場合、Unix システム コールが予期せずブロックされたり、デッドロックさえ発生する可能性があります (このトピックの詳細については、Java exec - Java ProcessBuilder と Process を使用してシステム プロセスを実行する (パート 3) (2012) .

に基づいて次の Java サンプル コードを試してみてください。ThreadedStreamHandler.java実行されます(最新の Eclipse Java EE IDE for Web Developers - Mac OS X バージョンを使用して動作しました) SystemCommandExecutor.javaProcessBuilderExample.javacommands.add("ssh localhost /tmp/test.sh");

# References: 
#
# - "Java exec - execute system processes with Java ProcessBuilder and Process (part 3)" (2012), 
# http://alvinalexander.com/java/java-exec-processbuilder-process-3
# 
# - "Running system commands in Java applications" (2012), 
# http://alvinalexander.com/java/edu/pj/pj010016
# 
# - "When Runtime.exec() won't: Navigate yourself around pitfalls related to the Runtime.exec() method" (2000),
# http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html

mkdir -vp /tmp/com/devdaily/system
cd /tmp/com/devdaily/system
curl -LO http://alvinalexander.com/java/edu/java-exec/ProcessBuilderExample.java
curl -LO http://alvinalexander.com/java/edu/java-exec/SystemCommandExecutor.java
curl -LO http://alvinalexander.com/java/edu/java-exec/ThreadedStreamHandler.java
cd ../../..

# create commands.add("ssh localhost /tmp/test.sh");
printf '%s\n' 'H' ',s|ls -l.*tmp|ssh localhost /tmp/test.sh|' 'wq' |
    ed -s com/devdaily/system/ProcessBuilderExample.java

echo '
#!/bin/bash
tail -f /private/var/log/system.log > /tmp/output.log &
echo "THE END"
exit 0
' > /tmp/test.sh

chmod +x /tmp/test.sh

javac com/devdaily/system/ProcessBuilderExample.java
java com/devdaily/system/ProcessBuilderExample


java -version
# java version "1.6.0_31"
# Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-10M3646)
# Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-415, mixed mode)


# Eclipse Java EE IDE for Web Developers (Mac OS X version).
# Version: Juno Service Release 2
# Build id: 20130225-0426
#
# use the following menu sequences:
# Window --> Show View --> Console
# Run --> External Tools --> External Tools Configuration... --> Program (double-click) --> New_configuration
# Location: /usr/bin/java
# Working Directory: /tmp
# Arguments: com/devdaily/system/ProcessBuilderExample
于 2013-03-10T07:21:45.923 に答える
0

nohup で試してください:

nohup tail -f /var/log/dmesg > /tmp/output.log &

SSH は、すべてのプロセスが tty を閉じるのを待ってから終了することがあります。nohupstdin/dev/nullと stdout/stderr をファイルに設定するため、SSH はすぐに終了できます (「THE END」が表示されないようにしている可能性のあるバッファーをフラッシュします)。

于 2013-02-01T17:49:50.247 に答える