Мне надо смастерить следующий агрегат:
data-source1 → filter1 →
↘
→ comparator → result
↗
data-source2 → filter2 →
:wall:
Что принимает на вход компаратор? Точнее -- в каком виде?
Unix-way это три слова: сопли, костыли, скотч.
Цитата: oort от декабря 7, 2010, 17:20
Что принимает на вход компаратор? Точнее -- в каком виде?
А какая разница?
Цитата: oort от декабря 7, 2010, 17:20
Что принимает на вход компаратор? Точнее -- в каком виде?
Логично предположить, что текстовые строки. Потому что в unix-way только они и предусмотрены. ;D
Цитата: Алексей Гринь от декабря 7, 2010, 17:30
Unix-way это три слова: сопли, костыли, скотч.
Текущая
реализ помойка просто бесит. За n-цтать лет никакого порядка так и не навели. Позорники!
Цитата: myst от декабря 7, 2010, 17:35
Цитата: oort от Вчера в 18:20ЦитироватьЧто принимает на вход компаратор? Точнее -- в каком виде?
А какая разница?
Если он еще не написан -- его можно написать так, чтобы он удовлетворял описанным условиям. Если он уже написан не в unix way, то кто ж ему виноват.
Дело какбэ вообще не в типе данных.
Цитата: oort от декабря 8, 2010, 11:18
Если он еще не написан -- его можно написать так, чтобы он удовлетворял описанным условиям. Если он уже написан не в unix way, то кто ж ему виноват.
Так вопрос же и был — как это нормально написать в unix-way, если stdin только один?
Цитата: Demetrius от декабря 8, 2010, 14:33
Так вопрос же и был — как это нормально написать в unix-way, если stdin только один?
Именно. Нужны нелинейные конвейеры. Собственно средства для этого есть, но за 30 лет никто так и не почесался сделать. :(
А зачем через stdin? Насколько я понимаю, unix way состоит в обработке данных по частям, а не в том, что эти данные обязательно должны передаваться через пайп, и никак иначе.
В данном случае -- таки через пайп, но именованный. Каждый фильтр пишет в свой пайп, а компаратор читает из обоих в том порядке, в котором ему больше нравится.
Цитата: oort от декабря 8, 2010, 15:32
А зачем через stdin? Насколько я понимаю, unix way состоит в обработке данных по частям, а не в том, что эти данные обязательно должны передаваться через пайп, и никак иначе.
У вас какой-то другой unix way.
Цитата: oort от декабря 8, 2010, 15:32
В данном случае -- таки через пайп, но именованный. Каждый фильтр пишет в свой пайп, а компаратор читает из обоих в том порядке, в котором ему больше нравится.
А вот с этого момента поподробнее, пожалуйста, с sello'вскими примерами и coreutils.
mkfifo /tmp/fifo{1,2}
prog1 | filter1 > /tmp/fifo1 &
prog2 | filter2 > /tmp/fifo2 &
comparator /tmp/fifo{1,2}
Или я неправильно понял постановку задачи?
Это ниинтересна. Пространство имён файловой системы всё равно засирается.
Ну, все-таки в любой юникс-вейной ОС есть /tmp.
Цитата: oort от декабря 8, 2010, 17:00
Ну, все-таки в любой юникс-вейной ОС есть /tmp.
Это ничего не меняет. Костыльные костыли. А разгадка — в безблагодатности одномерного конвейера.
Так смысл поста топикстартера в решении задачи, или все же обгадить unix-way? Не нравится, не используй. А то начинается, "аа, тут не так, аа все это фигня"))
Ну давайте уже Ваши решения этой задачи без побочных эффектов.
Цитата: myst от декабря 8, 2010, 16:53
Это ниинтересна. Пространство имён файловой системы всё равно засирается.
Достаточно сделать имена уникальными (на случай, если наш скрипт вызывается одновременно из нескольких процессов). Представим себе костыль (kostyl), который генерирует уникальное имя, создает фифо с этим именем, выдает это имя через стандартный вывод, а стандартный ввод копирует в фифо. Тогда с его использованием команда будет выглядеть следующим образом:
comparator `prog1|filter1|kostyl` `prog2|filter2|kostyl`
Минус: насколько я могу понять, фильтры и компаратор будут выполняться в этом случае последовательно друг за другом, а не одновременно.
Цитата: Python от декабря 9, 2010, 19:39
Достаточно сделать имена уникальными (на случай, если наш скрипт вызывается одновременно из нескольких процессов). Представим себе костыль (kostyl), который генерирует уникальное имя, создает фифо с этим именем, выдает это имя через стандартный вывод, а стандартный ввод копирует в фифо.
Чё его представлять, он mktemp называется.
Убирать в пространстве имён будет дядя?
Я уже заколебался создавать временные файлы и удалять их потом.
Цитата: myst от декабря 9, 2010, 19:50
Убирать в пространстве имён будет дядя?
В случае Windows-way, очень часто убирает именно дядя пользователь. Если имя в папке temp, ни с чем не пересекается, то кому оно мешает?
Цитата: Python от декабря 9, 2010, 20:12
В случае Windows-way, очень часто убирает именно дядя пользователь.
Что такое Windows-way?
Цитата: Python от декабря 9, 2010, 19:39
comparator `prog1|filter1|kostyl` `prog2|filter2|kostyl`
Минус: насколько я могу понять, фильтры и компаратор будут выполняться в этом случае последовательно друг за другом, а не одновременно.
Как это вообще будет работать? kostyl заблокируется на пайпе, и ага.
Цитата: myst от декабря 9, 2010, 20:40
Как это вообще будет работать? kostyl заблокируется на пайпе, и ага.
Действительно. Но если костыль копирует ввод в обычный файл и возвращает его имя, по идее, должно работать.
Windows-way — это пять слов: сопли, костыли, скотч, красивая обертка :)
Цитата: Python от декабря 9, 2010, 21:40
Но если костыль копирует ввод в обычный файл и возвращает его имя, по идее, должно работать.
После того как всё скопирует.
Хочется нелинейности и безо всяких побочных эффектов. Накидал фильтров, сепараторов, смесителей etc. — и щастье.
Кто мешает загнать data-source1 и data-source2 в одну задачу? Всё равно на один выход одного приходится ровно один выход другого.
Тогда эта программа уже будет выполнять больше одной вещи => это не юниксвей
Код работоспособного костыля, о котором шла речь выше:
MYFILE=`mktemp`
echo $MYFILE
cat> $MYFILE
Без параллельности, но работает.
Попытки вклинить туда пайп:
MYFIFO=`mktemp -u`
mkfifo $MYFIFO
echo $MYFIFO
cat> $MYFIFO &
как и следовало ожидать, не дали результатов — вешается.
Пришел к выводу, что проще создать собственную надстройку над шеллом (получающую команды в удобочитаемом синтаксисе, например:
comparator `program1|filter1|` `program2|filter2|`
и преобразовывающую их в серию выполнимых команд), чем заставить костыль работать в многопоточном режиме. Проще всего, конечно, сделать то же, что и в примере oort'a (Unix-way не торт№12) (http://lingvoforum.net/index.php/topic,29761.msg703870.html#msg703870), но имена фифо желательно генерировать автоматически.
Цитата: Alone Coder от декабря 9, 2010, 22:53
Кто мешает загнать data-source1 и data-source2 в одну задачу? Всё равно на один выход одного приходится ровно один выход другого.
Чово?
Пример: есть два файла с таблицами (длина, частота, словоформа); требуется узнать, каких словоформ не хватает в первом первом файле и наоборот.
Тогда вам многозадачность ни разу не поможет.
Цитата: Alone Coder от декабря 10, 2010, 12:02
Тогда вам многозадачность ни разу не поможет.
А мне она ни разу и не нужна.
Я тут порылся в мануалах к башу. Кажется, там все же есть то, что нам требуется. Unix-way — торт :)
Цитировать
Process Substitution
Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files. It takes the form of <(list) or >(list). The process list is run with its input or output connected to a FIFO or some file in /dev/fd. The name of this file is passed as an argument to the current command as the result of the expansion. If the >(list) form is used, writing to the file will provide input for list. If the <(list) form is used, the file passed as an argument should be read to obtain the output of list.
When available, process substitution is performed simultaneously with parameter and variable expansion, command substitution, and arithmetic expansion.
Цитата: myst от декабря 7, 2010, 13:00
Мне надо смастерить следующий агрегат:
data-source1 → filter1 →
↘
→ comparator → result
↗
data-source2 → filter2 →
:wall:
comparator <(filter
1<data-source
1) <(filter
2<data-source
2) >result
Цитата: oort от декабря 8, 2010, 16:23
mkfifo /tmp/fifo{1,2}
prog1 | filter1 > /tmp/fifo1 &
prog2 | filter2 > /tmp/fifo2 &
comparator /tmp/fifo{1,2}
comparator <(prog1 | filter1) <(prog2 | filter2)
Именованные каналы по-прежнему обламывают. :(
Цитата: myst от декабря 12, 2010, 13:52
Именованные каналы по-прежнему обламывают. :(
Вас утешит, что они автоматически удаляются сразу после завершения использующей их команды (во всяком случае в цѵгвине, с убунтой не проверял, но, думаю, там тоже):
$ echo <(ls)
/proc/self/fd/63
$ cat /proc/self/fd/63
cat: /proc/self/fd/63: No such file or directory
А вот это совсем другое дело! ;up:
Цитата: http://zsh.sourceforge.net/Intro/intro_7.html
Note that the shell creates a temporary file, and deletes it when the command is finished.
Торт.
Очередной хак вокруг кривой архитектуры — ничего удивительного. Меня ещё очень веселят временные файлы-мьютексы, чтобы нельзя было открыть две instances программы на один и тот же файл.
Цитата: Алексей Гринь от декабря 13, 2010, 02:51
Очередной хак вокруг кривой архитектуры — ничего удивительного.
Да, но что поделать? Замены нет. :(