Вы можете использовать здесь документ и. исходники для эффективной, POSIX-дружественной модели общего коллекционера.
. 8<<-\IOHERE /proc/self/fd/8
command
…
fn() { declaration ; } <<WHATEVER
# though a nested heredoc might be finicky
# about stdin depending on shell
WHATEVER
cat -u ./stdout | ./works.as >> expect.ed
IOHERE
Когда вы открываете heredoc, вы сигнализируете оболочке с входным токеном IOHERE, что она должна перенаправить свой ввод в указанный вами дескриптор файла, пока не встретит другой конец вашего токен-ограничителя. Я посмотрел вокруг, но я не видел много примеров использования номера fd перенаправления, как я показал выше в сочетании с оператором heredoc, хотя его использование четко указано в основных рекомендациях по командам оболочки POSIX. Большинство людей просто указывают на stdin и стреляют, но я нахожу, что использование скриплетов для поиска источников может таким образом сохранить stdin свободным, и приложения не будут жаловаться на заблокированные пути ввода-вывода.
Содержимое heredoc передается в указанный вами файловый дескриптор, который, в свою очередь, затем интерпретируется как шелл-код и выполняется командой. встроенный, но не без указания конкретного пути для. , Если путь / proc / self создает проблемы, попробуйте / dev / fd / n или / proc / $$. Этот же метод работает на трубах, кстати:
cat ./*.sh | . /dev/stdin
Это, по крайней мере, так же неразумно, как кажется. Конечно, вы можете сделать то же самое с sh, но цель. - выполнить в текущей среде оболочки, что, вероятно, вам и нужно, и, в зависимости от вашей оболочки, с большей вероятностью будет работать с heredoc, чем со стандартным анонимным каналом.
Во всяком случае, как вы, наверное, заметили, я до сих пор не ответил на ваш вопрос. Но если вы думаете об этом, точно так же, как heredoc направляет весь ваш код в. In, он также предоставляет вам одну простую точку зрения:
. 5<<EOIN /dev/fd/5 |\
tee -a ./log.file | cat -u >$(tty)
script
…
more script
EOIN
Таким образом, весь вывод терминала из любого кода, выполняемого в вашем heredoc, передается по каналу. как само собой разумеющееся и может быть легко отсоединено от одной трубы. Я включил небуферизованный вызов cat, потому что мне неясно текущее направление stdout, но оно, вероятно, избыточно (почти наверняка так, как написано в любом случае), и конвейер, вероятно, может закончиться сразу же.
Вы можете также подвергнуть сомнению недостающую кавычку во втором примере. Эту часть важно понять, прежде чем приступить к работе, и она может дать вам несколько идей о том, как ее можно использовать. Ограничитель heredoc в кавычках (до сих пор мы использовали IOHERE и EOIN, а первый, который я цитировал с обратной косой чертой, хотя «одинарные» или «двойные» кавычки служили бы той же цели), запретит оболочке выполнять любое расширение параметров в содержимое, но ограничитель без кавычек оставит его содержимое открытым для расширения. Последствия этого когда у тебя наследственный. источники драматичны:
. 3<<HD ${fdpath}/3
: \${vars=$(printf '${var%s=$((%s*2))},' `seq 1 100`)}
HD
echo $vars
> 4,8,12…
echo $var1 $var51
> 4 104
Поскольку я не цитировал ограничитель heredoc, оболочка расширила содержимое во время его чтения и перед передачей полученного дескриптора файла. выполнить. По сути, это привело к тому, что команды были проанализированы дважды - в любом случае расширяемые. Поскольку я указал обратную косую черту в расширении параметра $ vars, оболочка проигнорировала свое объявление при первом проходе и удалила только обратную косую черту, чтобы все расширенное содержимое printf могло быть оценено как ноль, когда. Источник сценария на втором проходе.
Эта функциональность в основном именно то, что может обеспечить встроенная опасная оболочка eval, даже если цитирование гораздо проще обрабатывать в heredoc, чем в eval, и может быть столь же опасным. Если вы не планируете это тщательно, вероятно, лучше всего указывать ограничитель "EOF" по привычке. Просто говорю.
РЕДАКТИРОВАТЬ: Э, я оглядываюсь назад на это и думаю, что это слишком много. Если ВСЕ, что вам нужно сделать, это объединить несколько выходов в один канал, то самый простой способ - это просто использовать:
{ or ( command ) list ; } | tee -a ea.sy >>pea.sy
Завитки попытаются запустить содержимое в текущей оболочке, в то время как скобки будут выведены автоматически. Тем не менее, любой может сказать вам это и, по крайней мере, на мой взгляд,. Решение heredoc представляет собой гораздо более ценную информацию, особенно если вы хотите понять, как на самом деле работает оболочка.
Веселиться!