Описание тега homepod
Я пытаюсь использовать именованные каналы для обработки входных данных в параллельные, прежде чем вставить обратно вместе результаты. Я как-то работал, пока не появилась возможность принимать ввод из стандартного ввода (после этого ответа).
Здесь я сообщаю свои проблемы, используя упрощенный пример, который просто выбирает столбцы и делать никакой дополнительной обработки перед оклеиванием, но сам сценарий не более того.
Пример данных:
$ кот data.txt
А1 А2 А3 А4 А5
Б1 Б2 Б3 Б4 Б5
С4 С1 С3 С5 С2
Д1 Д2 Д3 Д4 Д5
Е1 Е2 Е3 Е4 Е5
Ф1 Ф2 Ф3 Ф4 Ф5
Г1 Г2 Г3 Г4 Г5
Н1 Н2 Н3 Н4 Н5
И1 И2 И3 И4 И5
J1 И J2 На J3 И J4 Не Сж5
К1 К2 К3 К4 К5
Л1 Л2 Л3 Л4 Л5
Скрипт, используя обычные файлы:
$ кот test_files.sh
#!/бин/Баш
get_1()
{
вырезать -ф1 - > ${1}
}
get_3()
{
вырезать -Ф3 - > ${1}
}
get_5()
{
вырезать -Ф5 - > ${1}
}
настройка()
{
директорию=$(mktemp -д)
на col1="собой${WORKDIR}/col1.txt"
кол3="собой${WORKDIR}/col3.txt"
col5="собой${WORKDIR}/col5.txt"
}
установки
очистки()
{
РМ -РЧ собой ${WORKDIR}
}
Если [ $# -GE в 1 -а-F "${1}" ]
тогда
кошка ${1} \
| тройник >(get_1 ${столбца col1}) \
| тройник >(get_3 ${кол3}) \
| get_5 ${col5} \
|| { Эхо "кошка не" && очистки && выход 1; }
еще
кошка - \
| тройник >(get_1 ${столбца col1}) \
| тройник >(get_3 ${кол3}) \
| get_5 ${col5} \
|| { Эхо "кошка не" && очистки && выход 1; }
интернет
вставить ${столбца col1} ${кол3} ${col5}
очистка
выход 0
Это один работает хорошо в обоих режимах:
$ ./test_files.sh data.txt
А1 А3 А5
Б1 Б3 Б5
С3 С5 С1
Д1 Д3 Д5
Е1 Е3 Е5
Ф1 Ф3 Ф5
Г1 Г3 Г5
Н1 Н3 Н5
И1 И3 И5
J1 И J3 И J5, В Нашей Стране
К1 К3 К5
Л1 Л3 Л5
$ кот data.txt | ./test_files.sh
А1 А3 А5
Б1 Б3 Б5
С3 С5 С1
Д1 Д3 Д5
Е1 Е3 Е5
Ф1 Ф3 Ф5
Г1 Г3 Г5
Н1 Н3 Н5
И1 И3 И5
J1 И J3 И J5, В Нашей Стране
К1 К3 К5
Л1 Л3 Л5
Вот версия, используя FIFO, где я выполняю экстракционной колонны в фоновом режиме и вставьте из порта:
$ кот test_fifos.sh
#!/бин/Баш
get_1()
{
вырезать -ф1 - > ${1}
}
get_3()
{
вырезать -Ф3 - > ${1}
}
get_5()
{
вырезать -Ф5 - > ${1}
}
настройка()
{
директорию=$(mktemp -д)
на col1="собой${WORKDIR}/col1.txt"
mkfifo ${столбца col1}
кол3="собой${WORKDIR}/col3.txt"
mkfifo ${кол3}
col5="собой${WORKDIR}/col5.txt"
mkfifo ${col5}
}
установки
очистки()
{
РМ -РЧ собой ${WORKDIR}
}
Если [ $# -GE в 1 -а-F "${1}" ]
тогда
кошка ${1} \
| тройник >(get_1 ${столбца col1}) \
| тройник >(get_3 ${кол3}) \
| get_5 ${col5} \
|| { Эхо "кошка не" && очистки && выход 1; } &
еще
кошка - \
| тройник >(get_1 ${столбца col1}) \
| тройник >(get_3 ${кол3}) \
| get_5 ${col5} \
|| { Эхо "кошка не" && очистки && выход 1; } &
интернет
вставить ${столбца col1} ${кол3} ${col5}
очистка
выход 0
Он работает при приеме входного файла в качестве аргумента:
$ ./test_fifos.sh data.txt
А1 А3 А5
Б1 Б3 Б5
С3 С5 С1
Д1 Д3 Д5
Е1 Е3 Е5
Ф1 Ф3 Ф5
Г1 Г3 Г5
Н1 Н3 Н5
И1 И3 И5
J1 И J3 И J5, В Нашей Стране
К1 К3 К5
Л1 Л3 Л5
Но при приеме данных из stdin выход:
$ кот data.txt | ./test_fifos.sh
$ # Ничего здесь, нет сообщение об ошибке
Делать некоторые эксперименты, чтобы создать минимальный пример, я понял, что код для обработки возможных ошибок, казалось, быть частью проблемы. Вот версия, используя FIFO и не пытаюсь обрабатывать ошибки:
$ кот test_fifos_noerr.sh
#!/бин/Баш
get_1()
{
вырезать -ф1 - > ${1}
}
get_3()
{
вырезать -Ф3 - > ${1}
}
get_5()
{
вырезать -Ф5 - > ${1}
}
настройка()
{
директорию=$(mktemp -д)
на col1="собой${WORKDIR}/col1.txt"
mkfifo ${столбца col1}
кол3="собой${WORKDIR}/col3.txt"
mkfifo ${кол3}
col5="собой${WORKDIR}/col5.txt"
mkfifo ${col5}
}
установки
очистки()
{
РМ -РЧ собой ${WORKDIR}
}
Если [ $# -GE в 1 -а-F "${1}" ]
тогда
кошка ${1} \
| тройник >(get_1 ${столбца col1}) \
| тройник >(get_3 ${кол3}) \
| get_5 ${col5} &
еще
кошка - \
| тройник >(get_1 ${столбца col1}) \
| тройник >(get_3 ${кол3}) \
| get_5 ${col5} &
интернет
вставить ${столбца col1} ${кол3} ${col5}
очистка
выход 0
Это работает в обоих режимах:
$ ./test_fifos_noerr.sh data.txt
А1 А3 А5
Б1 Б3 Б5
С3 С5 С1
Д1 Д3 Д5
Е1 Е3 Е5
Ф1 Ф3 Ф5
Г1 Г3 Г5
Н1 Н3 Н5
И1 И3 И5
J1 И J3 И J5, В Нашей Стране
К1 К3 К5
Л1 Л3 Л5
$ кот data.txt | ./test_fifos_noerr.sh
А1 А3 А5
Б1 Б3 Б5
С3 С5 С1
Д1 Д3 Д5
Е1 Е3 Е5
Ф1 Ф3 Ф5
Г1 Г3 Г5
Н1 Н3 Н5
И1 И3 И5
J1 И J3 И J5, В Нашей Стране
К1 К3 К5
Л1 Л3 Л5
Почему нет выхода, когда я обрабатывать возможные ошибки и использование порта при приеме данных из stdin?
Редактировать: некоторые отладки
Я добавил некоторые отладки, чтобы ошибка сценария:
$ кот test_fifos.sh
#!/бин/Баш
get_1()
{
>&2 Echo "а get_1"
вырезать -ф1 - > ${1}
}
get_3()
{
>&2 Echo "а get_3"
вырезать -Ф3 - > ${1}
}
get_5()
{
>&2 Echo "а get_5"
вырезать -Ф5 - > ${1}
}
настройка()
{
директорию=$(mktemp -д)
на col1="собой${WORKDIR}/col1.txt"
mkfifo ${столбца col1}
кол3="собой${WORKDIR}/col3.txt"
mkfifo ${кол3}
col5="собой${WORKDIR}/col5.txt"
mkfifo ${col5}
}
установки
очистки()
{
>&2 Echo "для очистки"
РМ -РЧ собой ${WORKDIR}
}
Если [ $# -GE в 1 -а-F "${1}" ]
тогда
>&2 Echo "а затем"
кошка ${1} \
| тройник >(get_1 ${столбца col1}) \
| тройник >(get_3 ${кол3}) \
| get_5 ${col5} \
|| { >&2 Echo "а кошка не" && очистки && выход 1; } &
еще
>&2 Echo "а еще"
кошка - \
| тройник >(get_1 ${столбца col1}) \
| тройник >(get_3 ${кол3}) \
| get_5 ${col5} \
|| { >&2 Echo "а кошка не" && очистки && выход 1; } &
интернет
>&2 Echo "а перед пастой"
вставить ${столбца col1} ${кол3} ${col5}
>&2 Echo "а после вставить"
очистка
выход 0
Вот что происходит, когда данные читаются со стандартного ввода:
$ кот data.txt | ./test_fifos.sh
еще
прежде чем вставить
get_3
get_5
get_1
после вставки
очистка
Так это значит, что другой
ветке выполняется.