3

私は少し混乱しています。これは昨日機能していましたが、ほとんど魔法のように、リダイレクトされた 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 <&3 > 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 <inputfifo_helper -jar $SERVER_FILE & echo $! > java.pid && fg

これは問題なく実行され、inputfifo にエコーすることができ、アプリはそれを取得し、コンソールに直接入力することもできました。それはスクリーンを通してさえ働きました。コード的には何も変更されていませんが、リダイレクトされた標準入力は機能しなくなりました。ファイル記述子を 9 または 127 に変更しようとしましたが、どちらも修正されませんでした。

私は何かを忘れていますか?壊れて機能しなくなった特定の理由はありますか?

(画面を切り離して起動し、少なくとも一度接続されていない限り入力の受信を拒否するため、画面自体に入力を送信する代わりにこれを使用しています。これがバグなのか意図されたものなのかはわかりません)

4

4 に答える 4

1

Javaプログラムをバックグラウンドに保つことができる場合は、制御端末から読み取り/dev/tty、while-readループを使用してinputfifoに書き込もうとすることができます。

# ...
java <inputfifo_helper -jar $SERVER_FILE & echo $! > java.pid

while IFS="" read -e -r -d $'\n' -p 'input> ' line; do
  printf '%s\n' "${line}"
done </dev/tty >inputfifo
于 2011-04-19T14:01:35.463 に答える
0

その予感..しかし、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# は異なります。これが何なのかわかりません (プロンプト コマンドに関連付けられている可能性があります)。

ls -l /dev/fd/(そして、診断用のスクリプトの先頭に追加します)

于 2011-03-24T23:17:35.743 に答える
0

指定されたコードの短縮バージョンを実行すると、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_helper ...
(exec cat <inputfifo_helper) &
pid3=$!
echo $pid1,$pid2,$pid3   
lsof -p $pid1,$pid2,$pid3
echo hello world > inputfifo
)


# show pids of cat commands
ps -U $(id -u) -axco pid,command | grep cat | nl    # using ps on Mac OS X
于 2011-03-25T19:17:39.380 に答える
0

単一の 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 <inputfifo_helper ...
cat < <(IFS="" read -r -d '' <&3 lines && printf '%s' "$lines")
)
于 2011-03-26T20:06:01.220 に答える