Conforme o exemplo a seguir e como na minha pergunta recente No bash, para onde foi o último caractere da nova linha? , Eu 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 muito significativa para uma ação do shell, ou seja, Substituição de Comando, para realmente excluir alguns dados da saída de comando que está substituindo ...
mas não consigo entender esse, como parece ser a antítese do que é suposto fazer .. ie. passar a saída de um comando de volta ao processo de script ... Reter um caractere me parece estranho, mas suponho que exista uma razão sensata para isso ... Estou ansioso para descobrir qual é esse motivo. .
Respostas:
Porque o shell não foi originalmente projetado para ser uma linguagem de programação completa.
É bastante difícil remover uma trilha
\n
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 ... deve haver uma maneira simples de removê-lo quando você deseja usá-lo em outro comando. A remoção automática com a$()
construção foi a solução escolhida.Então, talvez você aceite esta pergunta como resposta:
Você pode encontrar uma maneira simples de remover a trilha
\n
se isso não tiver sido feito automaticamente no seguinte comando?Observe que é necessário citar para impedir o esmagamento de espaços duplos que podem aparecer em datas formatadas.
fonte
shopt
alteração no comportamento padrão descrito, eu ficaria feliz novamente ... Acho difícil pensar que o Bash / Linux / Unix poluiria uma função tão crítica como "capturar stdout" apenas porquedate
não possui uma opção with / without '\ n' ... A correção óbvia seria que o bash (ou outro shell) possui umshopt
para isso ... Você conhece alguma? .. e você tem algum link de referência que fale dos porquês e dos motivos desta questão? ... e por que nãodate
tem uma opção \ n .. Deveria!$()
sintaxe alternativa preferida .{ echo -n "The current date is "; var="$(date; echo -e x)"; var="${var%x}"; echo -n "$var"; echo ", have a good day!"; }
.. assim seja :)date
iria funcionar, mas eu simplesmente usadodate
como um exemplo de qualquer comando ..Faz parte do padrão :
Obviamente, o padrão provavelmente é escrito dessa maneira, porque foi assim
ksh
que aconteceu ou algo assim, mas é o padrão e é um comportamento documentado. Se você não gostar, use Perl ou outra coisa que permita manter as novas linhas finais.fonte
Bem, isso faz sentido para mim. A nova linha está lá apenas em primeiro lugar, na saída normal do comando, para que o prompt apareça após a conclusão do comando 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
wc
comando gera 2 linhas de texto? Ah, não, ele gera um seguido por uma nova linha. Quando você analisawc
, não quer se preocupar com o fato de haver duas linhas de saída - não há realmente, apenas uma.fonte
\n
nostdout
fluxo original é removida pela Substituição de Comando. ie meus dados originais (dados muito importantes) têm novas linhas à direita removidas, mesmo quando os dados são agrupados em "aspas". Entendo razoavelmente como e por que o Word Splitting funciona, mas não faço a menor idéia do porquê da Substituição de Comando remover apenas novas linhas e apenas as linhas finais .Eu estava com o mesmo problema e encontrei o exemplo abaixo. Parece que citar ajudou a situação, pelo menos para mim:
http://tldp.org/LDP/abs/html/commandsub.html .
fonte
$str
, contendo a string"a b c"
. Se você passar$str
paraecho
sem aspas (echo $str
),echo
receberáa
,b
ec
como três argumentos distintos. Seu shell não se importa com o espaço em branco entre os argumentos.echo
imprimirá esses argumentos com espaços que separam cada um, para que você entenda"a b c"
. Se você passar a variávelecho
entre aspas (echo "$str"
), o shell a vê como um argumento e aecho
recebe como tal, para que o espaço em branco não seja recolhido. O mesmo se aplica às novas linhas.-n
bandeira,echo
adiciona uma nova linha à direita à saída, para que ambos os ecos no seu exemplo tenham novas linhas à direita. No entanto, se você tentarecho -n $dir_listing
ouecho -n "$dir_listing"
, verá que nenhuma nova linha à direita é impressa com ou sem aspas$dir_listing
, o que sugere que o problema está na substituição do comando.por que
echo "hello "
(sem as aspas) devora o espaço? o valor dos caracteres IFS é visto pelo shell como sendo delimitadores; portanto, os caracteres finais (que não delimitam nada) estão sendo removidos. A substituição de recomendação é simplesmente executar as recomendações em um sub-shell, portanto, segue a mesma lógica.fonte
x="hello "
ex="hello "
perderão todos os seus espaços finais se eles forem exibidos viaecho $x
... No entanto, apenas a última nova linha do Substituton de Comando será perdida.IFS
não tem nada a ver com remover novas linhas no final das substituições de comando.