Rura przypisuje zmienną


19

Dla uproszczenia chciałbym zrobić:

echo cart | assign spo;
echo $spo  

Wyjście: koszyk

Czy taka assignaplikacja istnieje?

Jestem świadomy wszystkich sposobów, aby to zrobić za pomocą substytucji.


Dlaczego chcesz to zrobić bez zamiany?
— Thanatos,

Lubię odwrotny przepływ notacji polskiej, gdy piszę tylko za pomocą potoków. Jestem znacznie szybszym kodowaniem, a jakość / szybkość kodów nie jest tak ważna. Również nie robię, kiedy łańcuchowanie jest łatwiejsze do komentowania części łańcucha i echa bieżącej mocy wyjściowej, zamiast usuwania tików itp.
— MageProspero,

Jeśli obawiasz się o łatwość debugowania, rozważ umieszczenie polecenia wstecznego w szeregu oddzielnych linii. A=$( some | command | here )z każdym some |, command |i herena własnej linii.
— roaima

Odpowiedzi:


11
echo cart | { IFS= read -r spo; printf '%s\n' "$spo"; }

Działa (przechowuje wynik echobez końcowego znaku nowej linii w spozmiennej), o ile echowypisuje tylko jedną linię.

Zawsze możesz zrobić:

assign() {
  eval "$1=\$(cat; echo .); $1=\${$1%.}"
}
assign spo < <(echo cart)

Następujące rozwiązania będą działać w bashskryptach, ale nie w bashmonicie:

shopt -s lastpipe
echo cat | assign spo

Lub:

shopt -s lastpipe
whatever | IFS= read -rd '' spo

Do przechowywania danych wyjściowych whateverdo pierwszych NUL znaków ( bashzmienne i tak nie mogą przechowywać znaków NUL) $spo.

Lub:

shopt -s lastpipe
whatever | readarray -t spo

do przechowywania danych wyjściowych whateverw $spo tablicy (jeden wiersz na element tablicy).


1
czy nie powinno być odstępu między IFS=i read?
— caesarsol,

Cała ostatnia rura. Potrzebny jest również zestaw notatek bocznych + m (ermmm lub -m) z wiersza poleceń, ponieważ zrobi to, ponieważ ostatnia rura nie działa z aktywną kontrolą zadań.
— MageProspero

17

Możesz zrobić coś takiego, jeśli użyjesz bash:

echo cart | while read spo; do echo $spo; done

Niestety zmienna „spo” nie będzie istniała poza pętlą „do zrobienia”. Jeśli możesz uzyskać to, co chcesz zrobić w pętli while, to zadziała.

Możesz właściwie robić dokładnie to, co napisałeś powyżej w ATT ksh (nie w pdksh ani mksh) lub we wspaniałym zsh:

% echo cart | read spo
% echo $spo
cart

Tak więc innym rozwiązaniem byłoby użycie ksh lub zsh.


1
Możesz użyć koprocesów w skorupie Korna (np. mksh): echo cart |& while read -p spo; do echo $spo; done( while IFS= read -p -r spo; do…Ale lepiej jest użyć )
— mirabilos

2

Jeśli dobrze rozumiem problem, chcesz przesłać standardowe wyjście do zmiennej. Przynajmniej tego szukałem i skończyłem tutaj. Więc dla tych, którzy podzielają mój los:

spa=$(echo cart)

Przypisuje cartdo zmiennej $spa.


2
Tak nazywają substytucję, której PO chciał uniknąć.
— Dmitrij Grigoriew

Przydało mi się to, wystarczyło przypisać ją do zmiennej, nie obchodziło mnie, jak się tam dostała!
— Chris Marisic

1

Jeśli chcesz tylko wyświetlić bieżący strumień potoku użyj cat.

echo cart | cat 

Jeśli chcesz kontynuować łańcuch poleceń, spróbuj użyć teepolecenia, aby wyświetlić dane wyjściowe.

echo cart | tee /dev/tty | xargs ls

Możesz użyć aliasu, aby skrócić polecenie.

alias tout='tee /dev/tty'
echo cart | tout | xargs ls

Dlaczego chcesz przesyłać dane wyjściowe do zwykłego cat?
— roaima

1
@roaima Niektóre polecenia rozpoznają, że działają na terminalu i zachowują się inaczej niż wtedy, gdy są wysyłane do potoku. W szczególności mogą one przycinać linie do bieżącej szerokości ekranu. W przypadku większości poleceń polecenie cat jest zbędne.
— BillThor

Ach, ok, widzę teraz to, co próbujesz zilustrować. echo | catKonstrukt wyrzucił mnie.
— roaima

1

Oto moje rozwiązanie problemu.

# assign will take last line of stdout and create an environment variable from it
# notes: a.) we avoid functions so that we can write to the current environment
#        b.) aliases don't take arguments, but we write this so that the "argument" appears
#            behind the alias, making it appear as though it is taking one, which in turn
#            becomes an actual argument into the temporary script T2.
# example: echo hello world | assign x && echo %x outputs "hello world"
alias assign="tail -1|tee _T1>/dev/null&&printf \"export \\\$1=\$(cat _T1)\nrm _T*\">_T2&&. _T2"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.