Tratar a entrada para o comando read como um comando em si

1

Digamos que eu defini essa função no script:

fct1() {
  local msg1=${@}
if [[ "${verb}" = 'tru' ]]; then
  echo "I say $msg1"
  sleep 1
  echo "i repeat"
  sleep 1
  echo "I saaaaaaaaay $msg1"
else
  echo "$msg1"
fi
}

Como eu faria para fazer um usuário chamar essa função de read ?

Estou pensando em algo como

read fct1 "aha aha ahaaaaa"

E a saída seria:

"I say aha aha ahaaaaa" "I repeat" "I saaaaaaaaay aha aha ahaaaaa"

Basicamente, como eu uso a entrada em read e não a armazeno em uma variável, mas a utilizo como um comando?

Obrigado.

    
por iamAguest 23.08.2018 / 09:42

3 respostas

2

Se você quisesse que a mensagem fosse lida como uma linha de stdin (digitada pelo usuário quando o script é usado em um terminal) e depois passada como argumento para a função, você poderia fazer:

fct1 "$(line)"

line não é mais um comando padrão, mas ainda bastante difundido. Você poderia substituí-lo por head -n1 , mas com algumas implementações, ele poderia ler mais de uma linha (embora ela produza apenas uma) quando a entrada não estiver vindo de um dispositivo terminal.

Com bash read , você teria que armazená-lo em uma variável. É para isso que read armazena a entrada em uma variável.

IFS= read -r line && fct1 "$line"

Com zsh , você pode usar a opção read que ecoa os dados lidos em vez de armazená-los em uma variável, então -e acima pode ser escrito lá como line :

fct1 "$(IFS= read -re)"

(isso é menos eficiente do que usar IFS= read -re com uma variável, pois precisamos separar um processo para que o zsh possa ler a saída de read ).

Claro, você também pode substituir seu:

local msg1=${@}

com

local msg1; IFS= read -r msg1 || return
    
por 23.08.2018 / 10:37
0

O utilitário read não permite o uso de retornos de chamada (não sei se alguma das ferramentas comuns do Unix funciona). Além disso, ele não exibe os dados lidos.

O que você teria que fazer é agrupar a chamada read em uma função que aceita o que o usuário está fornecendo e retorna a saída conforme você descreve. Como alternativa, use alguma outra ferramenta para ler a entrada e produzir a saída desejada, como awk .

Além disso, em geral, usar variable=$@ não está bem definido. Se você quiser os argumentos da linha de comando como uma lista de valores delimitados por espaço, use variable="$*" (assumindo o valor padrão da variável IFS ).

    
por 23.08.2018 / 09:57
0

Este é um pedido bastante incomum ... hmmm ... para obter alguma entrada do terminal na lista de parâmetros posicionais dessa função, tente

fct1 "$(cat)"
dfergerg
I say dfergerg
i repeat
I saaaaaaaaay dfergerg

Isso manterá cat até você inserir um caractere EOF (CTRL-D). Certifique-se de que a variável vert esteja definida como tru fora da função.

    
por 23.08.2018 / 10:01