Como criar uma função bash que lê stdin com aspas?

Eu estou precisando de uma função no bash que mostre tudo que o usuário digitou de forma literal, incluindo as aspas, já tentei os procedimentos abaixo:

  • f() { echo "$@"; } não mantém as aspas
  • f() { echo \"$@\"; } só adiciona aspas no inicio e fim da variável
  • f() { read var ; echo "$var"; } funciona, mas, é necessário rodar a função para depois inserir os argumentos, tornando inviável usa-lá dentro de scripts por exemplo…
  • Usar \ ou 2 aspas resolve o problema, mas, a escrita fica difícil: f it\'s \"ok\" ou f it"'"s '"'ok'"'

Eu quero uma função simples para escrever função it's "ok" e o bash me responder it's "ok" . Isso é possível?

A melhor maneira é:

cat <<FIM
It's "OK"
FIM

Isso vai imprimir todas as linhas entre <<FIM e e FIM (a linha solta)
Se você tiver um linha que vai estar escrito exatamente FIM (maiúsculas, minúsculas e pontuação), só mudar o FIM:

cat <<RONALDINHO
Era uma vez um mexilhão feio. "!"
Ele era tão feio que todo mundo morreu. '!'
FIM
RONALDINHO
4 curtidas

é possível criar uma função que use esta lógica para realizar o feito que estou tentando???

1 curtida

Infelizmente não. A não ser se você fizer a técnica que eu descrevi (chamada heredoc), o Bash vai interpretar todas as aspas sem o backslash (\) como os delimitadores de argumento para a função.

2 curtidas

Muito interessante esta forma de se fazer, eu fiz uma função para brincar :rofl::

função() { cat<<FIM
 "$@" 
FIM
   }

se escrever função qualquer coisa ele vai colocar as aspas, semelhantemente a f() { echo \"$@\"; }… A função mais próxima do que eu quero foi a que coloquei com o read, ela literalmente lê tudo que a pessoa digitar, mas, seria possivel usar uma função como esta num script?

f() { read var ; echo "$var"; } para usar isso eu preciso responder ao read, já tentei alterar o REPLY mas não tive resultado :sweat_smile:

Vc já testou sem aspas dupla

echo ‘$@’

Cara esquece acho que não dá certo

Pode tentar com

echo ${@}

No momento estou no celular , mas vejo depois …

1 curtida

Também, até q é interessante porque tenho a impressão de que ‘’ é mais literal do que “”, se vc fizer uma função com este código vai ver que ele sempre te retornará $@, ou seja, ele não nem mesmo ler a variável, mas caso vc use “$@” ele vai retornar tudo que vc escrever dps. Pode tentar com função ou com script, é uma brincadeira legal :sweat_smile: Vi o edit, oq vale é a intenção, o pessoal daqui é top :laughing:

Vc pode tentar em vez de echo o comando type acho que é isso

Depois eu vejo

É quase o que o @Capezotte disse só faltou mostrar como estruturar a função:

function teste (){
  # Essa variável vai receber a entrada
  local stdin
  # O comando read vai pegar o que você passou e armazenar na variável stdtin
  echo Bora ver "${@}"
}

teste <<EOL
"oi" 'ei'
EOL

Isso você pode usar num script, o bash trata suas funções como se fossem comandos do sistema, então o que funciona em um comando, funciona numa função também. Uma coisa interessante é que o modo não iterativo suporta pipelines também:

echo oi | teste
2 curtidas

ele não vai aceitar it’s “ok” como argumentos posicionais
por que o Bash interpreta as aspas simples e duplas.
Se vc digitar isso mesmo que tu falou
$ funcao it's "ok"
>
observe que o cursor vai para a linha seguinte que começará com um >
indicando que vc abriu uma citação com as aspas simples, mas ainda não terminou.
Para citar as aspas simples e duplas, vc tem que usar o método de citação do csh, que consiste em em adicionar um backslash na frente de um caráter para este ser lido literalmente.
assim:

$ echo it\'s \"ok\"

para pegar input de usuário facilmente, use o read que é um builtin.

2 curtidas

Buguei, eu n entendi oq esta função faz, testei ela aqui e ela abre para digitar assim como o read, porém ao dar enter ela da um echo na linha que eu digitei… Pra ser sincero to pesquisando pra tentar entender melhor :sweat_smile:

1 curtida

Cara, de todas que tentei foi a melhor alternativa até agr, o problema é: Legal, consigo usar esta função dentro de um terminal, mas, como faria para usar num script??? eu precisaria que o script usasse a função e respondesse ela depois… até tentei atribuir a variavel REPLY mas não deu certo, se tiver alguma ideia me diga, estou receptivo :pray:

1 curtida

Vc não chama ela, porque assim vc entra no modo iterativo, você usa ela como o @Capezotte fez com o cat ou usa um pipeline

2 curtidas

e se vc tentar capturar input do usuário como argumento posicional , vai encontrar problemas com caracters especiais como o * e talvez [] e ? (são globs), dependendo se o extglob do bash do cara estiver ativado…

Eu estou precisando de uma função no bash que mostre tudo que o usuário digitou de forma literal, incluindo as aspas.

pelo que vc falou aqui, me parece que seria o caso de se usar o read, mas não estou entendendo o caso de uso do seu script.
por que não manda todo código que conseguiu até agora aqui para nós entedermos melhor o que vc está querendo fazer?

OBS: uhm… sabe que stdin pode não ser input de usuário, eu me enganei.

se vc quer capturar o stdin, pode fazer de algumas formas.
vc quer capturar o stdin em uma variável para usar a variável diversas vezes?
pode fazer uma substituição de comando:
VARIAVEL="$( < /dev/stdin )"
mas daí o input deve estar vindo realmente de um pipe…

1 curtida

É um bom ponto, meu objetivo é modificar a escrita de um programa usando shell script, em parte tive sucesso porém tive alguns problemas, para entender melhor veja o exemplo:

entrada: ./script ~e'texto 1' ~e'texto 2' ~e"$var1" ~e"$var2"
comando executado: echo -n 'texto' ; echo -n 'texto' ; echo -n "$var1" ; echo -n "$var2"

Consegui fazer isso de 2 formas:

1ª) command="${*}" ; command="${*//~e/echo -e }"
2ª) command="${*}" ; command=echo "$*" | sed 's|~e|echo -e |g'

Porém das 2 formas tenho o problema que preciso esta fazendo marabalismo com as aspas… pra este programa funcionar preciso fazer algo como:

./script ~e"'texto1'" ~e"'texto2'" ~e'"$var1"' ~e'"$var2"'

Edit: Perguntei por função porque é bem mais simples de explicar, e se eu conseguir fazer com a função certamente funcionaria com scripts, porém, acabei empacando neste problema… Como eu poderia fazer um tradutor? O que eu fiz funciona, mas, queria encontrar uma forma que não precisasse de tanto marabalismo :sweat_smile:

Já tentou com printf ?

O echo é limitado…