管道输入到Bash中的Java程序

时间:2016-05-10 05:33:43

标签: java linux pipe

我有一个java程序:

public class ProcessMain {
    public static final void main(String[] args) throws Exception {        

        Scanner keyboard = new Scanner(System.in);
        boolean exit = false;
            do
            {   if(keyboard.hasNext()){
                    String input = keyboard.next();
                    System.out.println(input);
                    if( "abort".equals(input)){
                    ABORT();
                    exit = true;
                    }
                }else{
                    System.out.println("Nothing");
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }while (!exit);
        }

    private static void ABORT(){
        System.out.println("ABORT!!!!");
    }
}

在Linux中,一个脚本:

rm testfifo
mkfifo testfifo
cat > testfifo &
echo $!


java -cp "Test.jar" com.example.ProcessMain < testfifo

终端A运行脚本,“Nothing”可以每5秒打印一次。 然后终端B执行echo“abort”&gt; testfifo,但程序无法显示ABORT,它仍然每5秒显示一次。

请帮助!!

2 个答案:

答案 0 :(得分:2)

如果您只需要外部触发器来停止当前处理。您可以创建一个信号量文件,并在其他进程创建后立即停止。

请参阅以下代码段。

// it will check for the file in the current directory
File semaphore = new File("abort.semaphore");
semaphore.deleteOnExit();
System.out.println("run until exist: " + semaphore);
while (!semaphore.exists()) {
    System.out.println("Nothing");
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
System.out.println("ABORT!!!!");

只要文件abort.semaphore不存在,程序就会打印到控制台并等待五秒钟。

编辑在Linux上,您可以使用信号处理程序并将SIGABRT发送到正在运行的进程。

以下代码段使用内部专有API

import sun.misc.Signal;
import sun.misc.SignalHandler;

public class SigAbrt {

  private static volatile boolean abort = false;

  public static void main(String[] args) throws Exception {

    Signal.handle(new Signal("ABRT"), new SignalHandler () {
      public void handle(Signal sig) {
        System.out.println("got a SIGABRT");
        abort = true;
      }
    });

    for(int i=0; i<100; i++) {
      Thread.sleep(1000);
      System.out.print('.');
      if (abort) {
          System.out.println("ABORT");
          break;
      }
    }
  }
}

运行它

第一节

java SigAbrt

第二场

// first find the PID of SigAbrt
jps

会话二的示例输出

2323  Jps
4242  SigAbrt

现在向SIGABRT进程发送SigAbrt

kill -s SIGABRT 4242

会话一的输出示例

...........got a SIGABRT
.ABORT

答案 1 :(得分:0)

程序不在控制台上打印可能是因为您的testfifo文件为空。

试试这个:

printf "Hello\nMy\nFriend\nabort" > testfifo

java -cp "Test.jar" com.example.ProcessMain < testfifo

它会起作用。