Por que a Substituição de Comando do shell engloba um caractere de nova linha à direita?

23

Conforme o exemplo a seguir e como em minha pergunta recente No bash, onde foi que o caractere de nova linha à direita desapareceu? , quero saber "por que" isso acontece

  x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p 
# Output is: 610a62 
# The trailing newline from the 'echo' command
#   has been "deleted" by Command Substitution

Eu suponho que deve haver alguma razão significativa muito para uma ação shell, a saber, Substituição de Comando, para realmente excluir alguns dados da saída do comando que está substituindo ...
mas eu não consigo entender isso, pois parece ser a antítese do que é suposto fazer ... isto é. para passar a saída de um comando de volta para o processo de script ... Retendo um caractere parece estranho para mim, mas eu suponho que há uma razão sensata para isso ... Eu estou ansioso para descobrir o que é essa razão. .

    
por Peter.O 31.07.2011 / 14:46

5 respostas

18

Porque o shell não foi originalmente concebido para ser uma linguagem de programação completa.

É muito difícil remover um \n à direita de alguma saída de comando. No entanto, para fins de exibição, quase todos os comandos terminam sua saída com \n , então… tem que haver uma maneira simples de removê-lo quando você quiser usá-lo em outro comando. A remoção automática com a construção $() foi a solução escolhida.

Então, talvez você aceite essa pergunta como resposta:

Você pode encontrar uma maneira simples de remover o \n à direita se isso não for feito automaticamente no seguinte comando?

> echo The current date is "$(date)", have a good day!

Note que a citação é necessária para evitar a quebra de espaços duplos que podem aparecer em datas formatadas.

    
por 31.07.2011 / 16:59
18

Faz parte do padrão :

The shell shall expand the command substitution by executing command in a subshell environment (see Shell Execution Environment) and replacing the command substitution (the text of command plus the enclosing "$()" or backquotes) with the standard output of the command, removing sequences of one or more <newline>s at the end of the substitution.

Naturalmente, o padrão provavelmente é escrito dessa maneira porque foi assim que ksh o fez ou algo assim, mas é o padrão, e é um comportamento documentado. Se você não gostar, use Perl ou qualquer outra coisa que permita manter as novas linhas.

    
por 31.07.2011 / 19:14
6

Bem, isso faz sentido para mim. A nova linha só existe, em primeiro lugar, na saída normal do comando, de modo que o prompt apareça após o comando ser concluído em uma nova linha. A nova linha não faz parte da saída original na maioria dos casos, está lá para arrumar a tela. Quando você está analisando a saída de um comando, a nova linha no final geralmente é problemática. Por que o comando wc gera duas linhas de texto? Oh, isso não acontece, gera um seguido por uma nova linha. Quando você analisa wc você não quer se preocupar com o fato de que há duas linhas de saída - não há realmente, há apenas uma.

    
por 31.07.2011 / 15:13
0

Eu estava com o mesmo problema e encontrei o exemplo abaixo. Parece que citando ajudou a situação, pelo menos para mim:

link .

dir_listing='ls -l'
echo $dir_listing     # unquoted

# Expecting a nicely ordered directory listing.

# However, what you get is:
# total 3 -rw-rw-r-- 1 bozo bozo 30 May 13 17:15 1.txt -rw-rw-r-- 1 bozo
# bozo 51 May 15 20:57 t2.sh -rwxr-xr-x 1 bozo bozo 217 Mar 5 21:13 wi.sh

# The newlines disappeared.


echo "$dir_listing"   # quoted
# -rw-rw-r--    1 bozo       30 May 13 17:15 1.txt
# -rw-rw-r--    1 bozo       51 May 15 20:57 t2.sh
# -rwxr-xr-x    1 bozo      217 Mar  5 21:13 wi.sh
    
por 19.04.2013 / 02:17
-1

por que echo "hello " (sem as aspas) engole o espaço? o valor dos caracteres IFS é visto pelo shell como sendo delimitadores, portanto, os caracteres à direita (que não delimitam nada) estão sendo removidos. Recomendo a substituição é simplesmente executar os elogios em um sub-shell, por isso segue a mesma lógica.

    
por 31.07.2011 / 15:51