Pipe atribui variável


19

Para simplificar, eu gostaria de fazer:

echo cart | assign spo;
echo $spo  

Saída: carrinho

Existe um assignaplicativo assim?

Estou ciente de todas as maneiras de fazer isso usando a substituição.


Por que você quer fazer isso sem substituição?
Thanatos

Eu gosto do fluxo de notação polonês reverso ao escrever apenas com tubos. Eu sou uma codificação muito mais rápida e a qualidade / velocidade dos códigos não é tão importante. Também eu não quando o encadeamento é hella mais fácil para comentar as partes da cadeia e ecoar a saída de corrente em vez de apagar carrapatos etc.
MageProspero

Se você estiver preocupado com a facilidade de depuração, considere colocar o comando backticks em uma série de linhas separadas. A=$( some | command | here )com cada um de some |, command |e hereem sua própria linha.
roaima

Respostas:


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

Funcionaria (armazenaria a saída echosem o caractere de nova linha à direita na spovariável) desde que echoemita apenas uma linha.

Você sempre pode fazer:

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

As seguintes soluções funcionariam em bashscripts, mas não no bashprompt:

shopt -s lastpipe
echo cat | assign spo

Ou:

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

Para armazenar a saída de whateveraté os primeiros caracteres NUL ( bashvariáveis não pode armazenar caracteres NUL de qualquer maneira) no $spo.

Ou:

shopt -s lastpipe
whatever | readarray -t spo

para armazenar a saída de whateverna $spo matriz (uma linha por elemento da matriz).


1
não deveria haver um espaço entre IFS=e read?
caesarsol

Todos saudam o último cachimbo. Também é necessário definir o conjunto de notas laterais + m (ermmm ou -m) a partir de uma linha de comando, pois o último canal não funciona com o controle de trabalho ativo.
precisa saber é o seguinte

17

Você pode fazer algo assim, se você usar bash:

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

Infelizmente, a variável "spo" não existirá fora do loop while-do-done. Se você conseguir o que deseja dentro do loop while, isso funcionará.

Na verdade, você pode fazer quase exatamente o que escreveu acima no ATT ksh (não no pdksh ou mksh) ou no fabuloso zsh:

% echo cart | read spo
% echo $spo
cart

Portanto, outra solução seria usar ksh ou zsh.


1
Você pode usar coprocesses na Shell Korn (por exemplo mksh): echo cart |& while read -p spo; do echo $spo; done(na verdade, melhor usar while IFS= read -p -r spo; do…embora)
mirabilos

2

Se eu entendi o problema corretamente, você deseja canalizar stdout para uma variável. Pelo menos era o que eu estava procurando e acabei aqui. Então, para aqueles que compartilham o meu destino:

spa=$(echo cart)

Atribui cartà variável $spa.


2
É o que eles chamam de substituição, que o OP queria evitar.
Dmitry Grigoryev

Isso foi útil para mim, eu só precisava atribuí-lo a uma variável, não me importava como chegava lá!
Chris Marisic em 24/04

1

Se você deseja apenas exibir o fluxo atual de tubos, use cat.

echo cart | cat 

Se você deseja continuar sua cadeia de comandos, tente usar o teecomando para ecoar a saída.

echo cart | tee /dev/tty | xargs ls

Você pode usar um alias para encurtar o comando.

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

Por que você gostaria de canalizar a saída para uma planície cat?
roaima

1
@roaima Alguns comandos reconhecem que estão rodando em um terminal e se comportam de maneira diferente do que se estivessem enviando para um tubo. Em particular, eles podem truncar linhas para a largura da tela atual. Para a maioria dos comandos, o comando cat é redundante.
BillThor

Ah, ok, agora vejo o que você estava tentando ilustrar. A echo | catconstrução me jogou.
roaima 27/01

1

Aqui está a minha solução para o problema.

# 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"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.