Możesz użyć tutaj-doc i. pozyskaj go, aby uzyskać wydajny, przyjazny dla POSIX ogólny model kolektora.
. 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
Kiedy otworzysz heredoc, zasygnalizujesz powłoce token wejściowy IOHERE, że powinien przekierować swoje wejście do określonego deskryptora pliku, dopóki nie napotka drugiego końca tokena ograniczającego. Rozejrzałem się, ale nie widziałem wielu przykładów użycia numeru fd przekierowania, jak pokazano powyżej w połączeniu z operatorem heredoc, chociaż jego użycie jest jasno określone w podstawowych wytycznych POSIX dotyczących poleceń powłoki. Większość ludzi po prostu wskazuje to na standardowe wejście i strzela, ale uważam, że w ten sposób skryptlety źródłowe mogą uwolnić standardowe wejście i standardowe aplikacje nie mogą narzekać na zablokowane ścieżki wejścia / wyjścia.
Zawartość heredoc jest przesyłana strumieniowo do określonego deskryptora pliku, który z kolei jest interpretowany jako kod powłoki i wykonywany przez. wbudowane, ale nie bez określonej ścieżki. . Jeśli ścieżka / proc / self sprawia ci kłopotów, spróbuj / dev / fd / n lub / proc / $$. Ta sama metoda działa na rurach, nawiasem mówiąc:
cat ./*.sh | . /dev/stdin
Jest prawdopodobnie co najmniej tak nierozsądny, jak się wydaje. Możesz zrobić to samo z sh, oczywiście, ale celem. Jest wykonanie w bieżącym środowisku powłoki, co jest prawdopodobnie tym, czego chcesz, i, w zależności od twojej powłoki, jest znacznie bardziej prawdopodobne, aby pracować z heredoc niż ze standardową anonimową potokiem.
W każdym razie, jak zapewne zauważyłeś, wciąż nie odpowiedziałem na twoje pytanie. Ale jeśli się nad tym zastanowić, w ten sam sposób, w jaki heredoc przesyła strumieniowo cały kod do pliku .s, zapewnia również pojedynczy, prosty punkt:
. 5<<EOIN /dev/fd/5 |\
tee -a ./log.file | cat -u >$(tty)
script
…
more script
EOIN
Więc wszystkie terminale stdout z dowolnego kodu wykonanego w twoim heredoc są wysyłane z. oczywiście i można go łatwo zdjąć z jednej rury. Dołączyłem niebuforowane wołanie kota, ponieważ nie jestem pewien, co do obecnego kierunku wyjścia, ale prawdopodobnie jest ono zbędne (prawie na pewno jest tak napisane), a rurociąg może prawdopodobnie skończyć się na tee.
W drugim przykładzie możesz również zakwestionować brakujący cytat z odwrotnym ukośnikiem. Ta część jest ważna do zrozumienia przed przystąpieniem i może dać ci kilka pomysłów na temat jej wykorzystania. Cytowany ogranicznik heredoc (do tej pory używaliśmy IOHERE i EOIN, a pierwszy cytowany z odwrotnym ukośnikiem, chociaż „pojedyncze” lub „podwójne” cudzysłowy służyłyby temu samemu celowi) zablokuje powłoce wykonywanie jakiegokolwiek rozszerzenia parametrów na zawartość, ale niecytowany ogranicznik pozostawi jego zawartość otwartą do rozbudowy. Konsekwencje tego, kiedy twój heredok jest. źródła są dramatyczne:
. 3<<HD ${fdpath}/3
: \${vars=$(printf '${var%s=$((%s*2))},' `seq 1 100`)}
HD
echo $vars
> 4,8,12…
echo $var1 $var51
> 4 104
Ponieważ nie zacytowałem ogranicznika heredoc, powłoka rozszerzyła zawartość, czytając ją i przed podaniem wynikowego deskryptora pliku. wykonać. Zasadniczo spowodowało to dwukrotne przeanalizowanie poleceń - w każdym razie poleceń rozwijalnych. Ponieważ odwrócony ukośnik zacytowałem rozszerzenie parametru $ vars, powłoka zignorowała swoją deklarację przy pierwszym przejściu i usunęła tylko odwrotny ukośnik, aby cała rozwinięta zawartość printf mogła być oceniona przez zero, kiedy. pozyskałem skrypt w drugim przebiegu.
Ta funkcjonalność jest dokładnie tym, co może zapewnić niebezpieczna wbudowana powłoka eval, nawet jeśli cytowanie jest znacznie łatwiejsze w heredoc niż w eval, i może być równie niebezpieczne. O ile nie zaplanujesz go dokładnie, prawdopodobnie najlepiej jest przyzwyczaić się do ogranicznika „EOF”. Tylko mówię.
EDYCJA: Eh, patrzę wstecz i myślę, że to trochę za dużo. Jeśli WSZYSTKO, co musisz zrobić, to połączyć kilka danych wyjściowych w jedną potok, to najprostszą metodą jest użycie:
{ or ( command ) list ; } | tee -a ea.sy >>pea.sy
Curlies spróbują uruchomić zawartość w bieżącej powłoce, podczas gdy parens automatycznie się wyłączy. Mimo to, każdy może ci to powiedzieć i, przynajmniej moim zdaniem,. Rozwiązanie heredoc jest znacznie bardziej wartościową informacją, szczególnie jeśli chcesz zrozumieć, jak naprawdę działa powłoka.
Baw się dobrze!