O código a seguir descreve melhor a situação. Por que a última linha não está exibindo o caractere de nova linha à direita? A saída de cada linha é mostrada no comentário. Estou usando o GNU bash, versão 4.1.5
echo -n $'a\nb\n' | xxd -p # 610a620a
x=$'a\nb\n' ; echo -n "$x" | xxd -p # 610a620a
echo -ne "a\nb\n" | xxd -p # 610a620a
x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p # 610a62
tmp=$(somecommand; echo a); tmp=${tmp%a}
tmp=$(somecommand; echo a)
... Isso certamente levou o ponto para casa ... Até eu ver o exemplo, minha tendência ainda seria usarecho -n a
... mas, é claro !, não há necessidade de o-n
, porque Comando Substituição irá remover o final de linha introduzida em qualquer caso! ... graças ...Respostas:
A função de substituição de comando
$()
(e seu primo, o backtick) remove especificamente as novas linhas finais. Esse é o comportamento documentado e você deve sempre estar ciente disso ao usar a construção.As novas linhas dentro do corpo do texto não são removidas pelo operador de substituição, mas também podem ser removidas ao dividir palavras no shell, portanto, como isso depende depende se você usou aspas ou não. Observe a diferença entre esses dois usos:
No segundo exemplo, a saída não foi citada e a nova linha foi interpretada como uma divisão de palavras, fazendo com que ela apareça na saída como um espaço!
fonte
Ao usar a substituição de comando, o shell executa os comandos em um subshell, retornando seu stdout. nesse processo, os caracteres do IFS perdem seu significado (se não estiverem entre aspas), pois o elogio retorna palavras simples e divididas, de modo que os caracteres finais são removidos. Por exemplo:
e, mais praticamente,
pwd
funcionará mesmo se o nome do diretório tiver uma nova linha no meio, mas$(pwd)
não funcionará.A solução comum é adicionar algo no final do seu comando e removê-lo posteriormente.
fonte
echo "$(echo -e '\n')" | wc
, que gera1 0 1
, em comparação com o2 0 2
$(pwd)
e"$(pwd)"
, veja a resposta de Caleb.