Перенаправление ввода приложения (Java), но по-прежнему разрешает стандартный ввод в BASH - PullRequest
3 голосов
/ 24 марта 2011

Я немного сбит с толку, вчера у меня это работало, но оно просто перестало принимать перенаправленный стандартный ввод, почти магически.

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 иприложение получило его, и я мог набирать текст прямо в консоли.Это даже работало через экран.Абсолютно ничего в коде не изменилось, но переадресованный stdin перестал работать.Я попытался изменить дескриптор файла на 9 или даже 127, но ни один не исправил.

Я что-то забыл?Есть ли какая-то конкретная причина, по которой он сломался и больше не работает?

(я использую это вместо отправки ввода на сам экран, потому что я запускаю отключенный экран, и он отказывается принимать входные данные, если он не был присоединен по крайней мереоднажды, я не знаю, является ли это ошибкой или намерением)

Ответы [ 4 ]

1 голос
/ 19 апреля 2011

Если вы можете держать свою java-программу на заднем плане, вы можете попробовать прочитать с управляющего терминала /dev/tty и записать в inputfifo, используя цикл while-read.

# ...
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
0 голосов
/ 25 марта 2011

При запуске сокращенной версии данного кода выдается сообщение об ошибке ввода / вывода:

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
0 голосов
/ 26 марта 2011

Попробуйте использовать один fifo и повторить эхо в дескрипторе файла r / w. Используйте символ ASCII NUL для завершения ввода (строк), чтобы Команда чтения продолжает чтение до нулевого байта (или 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")
)
0 голосов
/ 25 марта 2011

Это догадка ... но может ли быть что-то еще, прикрепленное к 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 # # proc, на который указывает fd3, отличается - я понятия не имею, о чем речь (возможно, он связан с моей командой приглашения), но fd 3 занят, попробуйте fds # 5-9

(и добавить ls -l /dev/fd/ вверху скрипта для диагностики)

...