echo "a b" | perl -e 'open($OUT[$_], "|$ARGV[$_]") or die "$!:$ARGV[$_]\n"for 0..$#ARGV; while (my $l = <STDIN>) { for (0..$#ARGV) { my $OUT = $OUT[$_]; print $OUT $l}} close($_) for @OUT' "cat -" "cat -"
В перл передается поток через stdin, там открываются локальные пайпы для stdin каждого переданного аргумента (являющегося произвольной командой допустимой в шелле) и в каждый такой пайп выводится копия потока.
А уже задача каждой команды как то обработать или просто вывести свою копию потока в stdout.
В данном примере указаны команды «cat -» и «cat -», т.е. создаются 2 копии потока и просто выводятся в stdout.
Естественно без отладки из головы каждый раз такую команду не наберешь, поэтому для практического применения вероятно нужно оформить в виде алиаса или отдельного скрипта (это легко сделать, т.к. тело команды не надо менять для разного числа аргументов).
Именно однострочником надо?
Потому что через именованные пайпы можно безо всякого оверхеда это делать, но там отдельными командами нужно создать/удалить пайп
Единственное непонятно — нафига использовать stderr не по назначению, когда размножение строк можно было точно так же и через stdout сделать: tee /dev/stdout
Если есть внешние ссылки на объект то для него не должен вызываться деструктор.
Деструктор вызывается только после того как последняя ссылка удалена.
Есть еще слабые ссылки, но там по определению сначала делается попытка создать сильную ссылку и она не удастся если объект в состоянии когда возможен вызов деструктора.
Так что ситуация когда деструктор вызывается параллельно с другими методами объекта — это просто потоконебезопасный код (внешний по отношению к объекту) и синхронизацией внутри объекта это нельзя устранить…
Это невалидный код. И синхронизация деструктора не сделает его валидным — она просто перенесет проблему из деструктора за его пределы.
Если есть ссылка доступная из нескольких потоков, то прежде чем вызывать для нее методы, надо ее скопировать в локальную переменную и после этого проверить копию на null.
При таком подходе (и при условии что подсчет ссылок в языке реализован атомарно, надеюсь в дельфи так и есть) деструктор вызывается только тогда когда никакие другие методы объекта не запущены.
Тут недавно кто-то обнаружил что у одного из гражданских министерств UK выделенный им блок /8 (51.0.0.0) уже много лет стоит никем не использованный (ни единого устройства в этом диапазоне).
Я думаю дело не в программистах, а в том что постоянно поддерживать две ветки регулярно развиваемого кода намного дороже чем однажды написать конвертер и иногда его фиксить.
Разница — огромная.
При поэлементном переносе конечный результат — один субъект, для которого достигнуто практическое бессмертие (другие субъекты при этом не задействованы).
При копировании результат — два субъекта, причем для исходного субъекта бессмертие не достигнуто, хотя весь сыр бор бор именно ради этого.
В перл передается поток через stdin, там открываются локальные пайпы для stdin каждого переданного аргумента (являющегося произвольной командой допустимой в шелле) и в каждый такой пайп выводится копия потока.
А уже задача каждой команды как то обработать или просто вывести свою копию потока в stdout.
В данном примере указаны команды «cat -» и «cat -», т.е. создаются 2 копии потока и просто выводятся в stdout.
Естественно без отладки из головы каждый раз такую команду не наберешь, поэтому для практического применения вероятно нужно оформить в виде алиаса или отдельного скрипта (это легко сделать, т.к. тело команды не надо менять для разного числа аргументов).
Просто возможно будет громоздко.
Чуть позже напишу решение.
mkfifo /tmp/fifo1; echo "a" | tee /tmp/fifo1 | (cat /tmp/fifo1 | (cmd1); cat - |(cmd2)); r m -f /tmp/fifo1Вместо cmd1 и cmd2 подставить соответственно команды для каждой ветки
Потому что через именованные пайпы можно безо всякого оверхеда это делать, но там отдельными командами нужно создать/удалить пайп
Но для данной задачи — сойдет. По крайней мере лучше чем хак через stderr
echo "a" | xargs -I % sh -c 'echo "%/1"; echo "%/2"'Применительно к данной статье:
echo "/usr/bin/gnote"| xargs -I % sh -c 'echo "%"; ldd "%"|cut -d" " -f3|grep "\S"'Если придумаю что-то — напишу сюда :)
Например абсолютно корректная программа может не работать в реальной системе (например из-за ошибки в ОС), а в математике такое невозможно.
Деструктор вызывается только после того как последняя ссылка удалена.
Есть еще слабые ссылки, но там по определению сначала делается попытка создать сильную ссылку и она не удастся если объект в состоянии когда возможен вызов деструктора.
Так что ситуация когда деструктор вызывается параллельно с другими методами объекта — это просто потоконебезопасный код (внешний по отношению к объекту) и синхронизацией внутри объекта это нельзя устранить…
Если есть ссылка доступная из нескольких потоков, то прежде чем вызывать для нее методы, надо ее скопировать в локальную переменную и после этого проверить копию на null.
При таком подходе (и при условии что подсчет ссылок в языке реализован атомарно, надеюсь в дельфи так и есть) деструктор вызывается только тогда когда никакие другие методы объекта не запущены.
Поэтому синхронизация в деструкторе бессмысленна.
Так что резервы еще есть :)
При поэлементном переносе конечный результат — один субъект, для которого достигнуто практическое бессмертие (другие субъекты при этом не задействованы).
При копировании результат — два субъекта, причем для исходного субъекта бессмертие не достигнуто, хотя весь сыр бор бор именно ради этого.
Достаточно слинковать статически с libc и другими библиотеками.