java中的后台进程监听stdin

java中的后台进程监听stdin,java,shell,stdin,background-process,Java,Shell,Stdin,Background Process,我必须制作一个java程序,当用户输入0时,它应该退出。用java代码编写没有问题 int cmd = read(); System.out.println("got command : " + cmd); if (cmd == 48) { // ASCII code for 0 System.exit(0); 我想在linux中使用start-stop脚本运行这个过程。我也可以使用&或nohup case "$1" in 'start') if [ -f myfifo ]

我必须制作一个java程序,当用户输入0时,它应该退出。用java代码编写没有问题

int cmd = read();
System.out.println("got command : " + cmd);
if (cmd == 48) { // ASCII code for 0
System.exit(0);
我想在linux中使用start-stop脚本运行这个过程。我也可以使用
&
nohup

case "$1" in    
  'start')
    if [ -f myfifo ]; then
      rm myfifo
    fi
    mkfifo myfifo
    cat > myfifo &
    echo $! > myfifo-cat-pid
    java -jar myjar.jar >/dev/null 2>&1 0<myfifo &
    echo "Started process: "$!
    ;;

  'stop')
    echo 0 > myfifo
    echo "Stopped process: "
    rm myfifo
    ;;
esac
中的案例“$1”
"开始")
如果[-f myfifo];然后
rm myfifo
fi
mkfifomyfifo
猫>我的FIFO&
echo$!>myfifo猫pid
java-jar myjar.jar>/dev/null 2>&1 0 myfifo
echo“已停止进程:”
rm myfifo
;;
以撒
我的问题是,只要我运行这个进程,它就会读取输入-1。当某个东西被显式地回显到stdinput时,即调用stop时,我想从stdinput读取。简单地说,我需要一个程序被shell脚本显式关闭。我已经尽力了。帮帮我

编辑:


我只想在用户按下q或任何类似事件时关闭程序,不想在代码中出现无限循环。如果可能的话,任何其他方法,如听其他事件,也会有所帮助。我的代码不应轮询事件。我尝试了
Jnotify
,它监视一个目录,并在该目录中创建或删除文件时引发一个事件。但不幸的是,他们没有对SunOS的支持(

由于管道中还没有数据,
read()
看到流的结尾,因此它返回
-1
。在读取流之前调用
available()
,以确保其中有信息。

事实上,
fifo
文件的行为似乎与您想象的不完全一样

read()
命令在管道上没有阻塞。您应该循环,直到获得数据:

    try {
        bis = new BufferedInputStream(System.in);
        while (true) {
            byte[] buffer = new byte[4096];
            if (bis.available() > 0) {
                bis.read(buffer, 0, bis.available());
                // do some clever thing
            } else {
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    } catch (IOException e) {
        // it failed...
    }
这将尝试读取,如果没有,则将等待50毫秒


M.

如果在shell脚本的顶部使用
set-M
(因此启用强制作业控制),您应该会看到一致的行为。

当您在脚本中设置命令的背景时,该命令的stdin将从
/dev/null
隐式重定向

# test by executing a script with ...
- cat > myfifo & lsof -p $!
+ cat 0<&0 > myfifo & lsof -p $!
#通过执行带有。。。
-cat>myfifo&lsof-p$!
+第0类myfifo和lsof-p$!

使用System.in.read();我也尝试过使用BufferReaderhum…你确定myfifo存在并且包含任何内容吗?System.in.read()可以正常工作。
mkfifo
?mkfifo创建fifo(队列)。System.in.read()即使我没有为进程分配任何stdin,也在读取。我的理解是,由于fifo中没有任何内容,因此它会达到EOF。在启动java程序之前,尝试创建fifo并在其中推送一些值,以确保在有内容读取时它能正常工作。是否检查了
myfifo
是否存在?是否可以读取从它开始?我忘了提到我也使用while循环完成了这项工作,但是它会不断地从stdin读取我不想要的,因为这是一个infinte循环,直到用户发送正确的命令。:(你需要什么?在程序中做些什么,同时收听stdin?当用户按下“q”时)它会停止你的程序?是的,这是我所需要的。但程序应该在后台运行,然后你必须将代码分成两个线程。一个线程将侦听fifo并在程序必须退出时将变量设置为true。另一个线程将执行此任务并检查每个循环是否可以继续或是否必须立即停止。是的,事实上,两者都是。如你所愿要使它们作为后台进程运行,它们必须处于无限模式。STDIN线程循环直到有要读取的内容,然后休眠,读取,休眠,…另一个线程执行该任务,检查它是否必须停止,执行该任务,检查。。。