Como fazer echo
e printf
barras invertidas tratamento em zsh
, bash
e outras conchas?
No zsh , recebo o seguinte comportamento:
$ echo "foo\bar\baz"
foaaz
$ echo "foo\\bar\\baz"
foaaz
$ echo 'foo\bar\baz'
foaaz
$ echo 'foo\\bar\\baz'
foo\bar\baz
Sob o bash , as coisas parecem um pouco mais consistentes:
bash$ echo "foo\bar\baz"
foo\bar\baz
bash$ echo 'foo\bar\baz'
foo\bar\baz
bash$
Mas, mais concretamente: como passar uma string contendo barras invertidas, como\\foo\bar\something
:
echo
printf
print
e obter exatamente a mesma string? (em zsh
e bash
)?
Aqui está outro experimento com funções no zsh:
function foo
{
echo -E '$1'
}
$ foo \\here\is\some\path
$1
Como posso imprimir apenas \\here\is\some\path
?
Atualização (Nota: isso já foi respondido no comentário de Stephane)
Eu tentei o seguinte no zsh 5.0.2:
function foo
{
printf '$s\n' $1
}
foo '\\some\path'
Mas isso imprime $s
?
printf
,echo
não é portátil no que diz respeito.'
por"
e chame-a por: foo '\\ here \ is \ some \ path' (caso contrário, o shell de chamada terá a chance de interpretar o '\' antes de chegar à função)'$s\n'
quando deveria ter sido usada'%s\n'
.Respostas:
zsh
echo
se comporta da maneira padrão, comobash
no modo UNIX. Ou seja, ele se expande\b
para o caractere ASCII BS conforme a especificação do UNIX exige.Não use
echo
para exibir seqüências arbitrárias, useprintf
:print -r -- "$1"
também funciona, mas éksh
/zsh
específico.echo -E - "$1"
trabalhar comzsh
e acredito que alguns BSDs.funciona em qualquer shell tipo Bourne, mesmo em algumas décadas em que não havia
printf
comando, mas gerou um novo processo, e realmente não é necessário hoje em dia, como temos emprintf
toda parte.E, a propósito, você precisa escapar de barras invertidas em uma linha de comando do shell, pois é especial para o shell (todos os shell, exceto
rc
), então:foo \\foo\bar
passaria a"\foo\bar"
string para afoo
qual não é possível reinventar a barra invertida perdida.fonte
printf '%s\n' "$var"
funciona para mim na linha de comando (zsh 5.0.2
ou seja, a mais recente), mas não dentro de uma função (veja minha atualização no OP). Por quê?printf '%s\n'
isso queprintf '$s\n'
você quer. Observe que você precisa citar variáveis em outros shells que não sejamzsh
("$1"
, not$1
) e a sintaxe de definição de função padrão éfoo() { ...; }
, embora qualquer shellbash
permitafoo() any-command
, efunction foo { .... }
é aksh
sintaxe.nova resposta: read -r var
e para exibir:
Deveria trabalhar.
Então, para a sua função foo:
resposta antiga abaixo (sem responder, mas talvez útil ^^)
apenas substitua cada um
\
por\\
dizer ao shell "que é um literall que\
eu quero". caso contrário (por exemplo, no zsh, no seu exemplo), pode ser que isso\b
signifique "1 backspace" ou qualquer outra coisa.você poderia, por exemplo, usar sed:
(veja como você também precisa escapar "\", para dizer a mesma coisa: "é literalmente" \ "eu quero) (e observe que eu o envolvo com '' e não" "para evitar que o shell interprete a maioria também)
fonte
read -r var
parece esperar pela entrada deSTDIN
. E se eu estiver passando isso como argumento? (por exemplo, foo\\here\is\some\path
)De um modo geral, você não pode, porque a barra invertida é o caractere de escape (e, como tal, deve ser escapado quando seu valor literal for necessário). O BASH fornece aspas simples para esse fim, no entanto, você não pode usar uma aspas simples para escapar dentro de uma string entre aspas simples.
Quanto à
echo
discrepância, é um componente interno que pode se comportar de maneira diferente entre as conchas (até certo ponto). Por exemplo, o BASH interno tem uma-e
opção que o instrui a interpretar seqüências de barra invertida - com isso você obtém o comportamento que viu no shell Z.fonte