重定向应用程序(java)的输入,但仍允许在BASH中使用stdin

我有点困惑,我昨天有这个工作,但它刚刚停止接受重定向的标准输入,几乎是神奇的。

set -m mkfifo inputfifo mkfifo inputfifo_helper ((while true; do cat inputfifo; done) > inputfifo_helper)& trap "rm -f inputfifo inputfifo_helper java.pid; kill $!" EXIT exec 3<&0 (cat  inputfifo)& NOW=$(date +"%b-%d-%y-%T") if ! [ -d "logs" ]; then mkdir logs fi if [ -f "server.log" ]; then mv server.log logs/server-$NOW.log fi java  java.pid && fg 

运行正常,我可以回复inputfifo并且应用程序得到它,我也可以直接输入它的控制台。 它甚至通过屏幕工作。 绝对没有任何代码改变,但重定向的stdin已停止工作。 我尝试将文件描述符更改为9,甚至127,但都没有修复它。

我忘了什么吗? 是否有一个特定的原因它打破了,不再有效?

(我正在使用它而不是向屏幕本身发送输入,因为我启动屏幕分离并拒绝接收输入,除非它已被附加到至少一次,我不知道这是一个错误还是有意)

如果你可以保持你的java程序背景,你可以尝试从控制终端/dev/tty读取并使用while-read循环写入inputfifo。

 # ... java  java.pid while IFS="" read -e -r -d $'\n' -p 'input> ' line; do printf '%s\n' "${line}" done inputfifo 

它是预感..但是fd 0还有其他东西吗?

在我的Linux上,我看到了这一点

 $ ls -l /dev/fd/ total 0 lrwx------ 1 nhed nhed 64 Mar 24 19:15 0 -> /dev/pts/2 lrwx------ 1 nhed nhed 64 Mar 24 19:15 1 -> /dev/pts/2 lrwx------ 1 nhed nhed 64 Mar 24 19:15 2 -> /dev/pts/2 lr-x------ 1 nhed nhed 64 Mar 24 19:15 3 -> /proc/6338/fd 

但是在每个后​​续的ls中,fd3指向的proc#是不同的 – 我不知道这是什么(也许它与我的提示命令有关),但fd 3被采用,尝试fds#5-9

(并在脚本顶部添加ls -l /dev/fd/以进行诊断)

运行给定代码的缩短版本会打印I / O错误消息:

 cat: stdin: Input/output error 

快速解决方法是将stderr重定向到此命令的/ dev / null。

在Mac OS X / FreeBSD上,你也可以尝试使用“cat -u”来禁用输出缓冲(从而避免cat输出缓冲问题)。

 rm -v inputfifo inputfifo_helper mkfifo inputfifo inputfifo_helper ( ((while true; do cat inputfifo; done) > inputfifo_helper) & # use of "exec cat" terminates the cat process automatically after command completion #((while true; do exec cat inputfifo; done) > inputfifo_helper) & pid1=$! exec 3<&0 # save stdin to fd 3 # following command prints: "cat: stdin: Input/output error" #(exec cat <&3 >inputfifo) & (exec cat <&3 >inputfifo 2>/dev/null) & pid2=$! # instead of: java  inputfifo ) # show pids of cat commands ps -U $(id -u) -axco pid,command | grep cat | nl # using ps on Mac OS X 

尝试使用单个fifo并将内容回显到ar / w文件描述符。 使用ASCII NUL字符终止(输入行)输入,以便读取命令继续读取,直到NULL字节(或EOF)。

 rm -v inputfifo mkfifo inputfifo ( exec 0>&- exec 3<>inputfifo # open fd 3 for reading and writing echo "hello world 1" >&3 echo "hello world 2" >&3 printf '%s\n\000' "hello world 3" >&3 # replaces: java