Problema de devolução de carro

3

Eu tenho isso em um script bash

DAY2="20130605"<Cr>
echo  "This is yesterday date:"$DAY2"end"

Por que a saída é a seguinte? Parece que há um retorno de carro em DAY2 , mas de onde ele vem?

ends is yesterday date:20130605
    
por user40634 06.06.2013 / 21:08

5 respostas

5

O retorno do carro coloca o cursor de volta ao começo da linha. Sua string de saída é:

    This is yesterday date:20130605<Cr>end

Exceto quando o terminal atinge o <Cr> , ele retorna o cursor para o início da linha e sobrescreve os caracteres que estão lá .

Em outras palavras, "Thi" é substituído por "end", produzindo:

    ends is yesterday date:20130605

Para fazer o que você parece estar tentando fazer, seu script deve ser parecido com isto:

   variable="text"
   echo "Some sentence $variable"

Qual será a saída

   Some sentence text

SE houver retorno de carro perdido, eles devem aparecer como ^M em vi (como disse Bruce)

Solução 1

A melhor maneira de remover retornos de carro ou outros caracteres não imprimíveis é com o comando tr com a opção -d , que exclui qualquer instância de um único caractere, com \r , que é a seqüência de escape para transporte retorno:

    tr -d '\r'

Isso removerá todas as devoluções de carro. Execute-o no script para remover todas as instâncias de retornos de carro e, em seguida, sobrescreva o arquivo de script original:

    tr -d '\r' yourscript.bash > temp
    mv temp yourscript.bash

Solução 2

ou enquanto em vi com o script aberto, digite:

    :%s/\r//g
    :wq

Para remover os retornos de carro dentro do documento, salve-o.

    
por 06.06.2013 / 22:35
2

Supondo que <Cr> represente um retorno de carro, remova o retorno de carro do final da primeira linha. Aqui está um one-liner para fazer isso por você:

sed -i '1s/\r//' script.sh

Para ver os retornos de carro no seu script, execute o seguinte.

od -c script.sh | grep --color=yes '\r'
    
por 06.06.2013 / 21:19
1

Use vi ou vim para ver o script bash em questão. Você deve ver qualquer retorno de carro perdido como '^ M' (caret, em) seqüências de dois caracteres. Use hjkl para mover o cursor sobre os retornos de carro, aperte 'x' para deletá-los, então ": wq" para sair de vi .

Meu palpite é que um retorno de carro perdido entrou no arquivo quando alguém moveu o arquivo para uma máquina Windows, editou-o com o Bloco de Notas ou o Wordpad e depois o moveu de volta para o linux.

    
por 06.06.2013 / 21:16
0

Exatamente como esse retorno de carro surgiu é difícil de dizer.

Se o script foi gerado por outro script ou aplicativo, pode ser um erro ou um infortúnio pretendido.

O mais provável é que você ou quem editou o arquivo pressionou acidentalmente uma combinação de teclas, fazendo com que CR fosse inserido.

Exemplos:

  • vim : Ctrl-v Ctrl-m
  • emacs: Ctrl-q Ctrl-m
  • E muitos outros.

Existem outros caracteres que também podem causar problemas, por exemplo No-break-space no código, etc. Isso geralmente causa bugs estranhos ao executar scripts ou compilar código.

Normalmente, uso vim e freqüentemente definido (tenho uma combinação de teclas para alterná-lo):

match Error /[^ -~\t]/

Ou seja: realce tudo, mas <space> to ~ em ASCII e tab com Error , normalmente branco em vermelho, etc.

Para arquivos de código, eu geralmente tenho isso configurado por padrão.

No retorno do carro do terminal normalmente faz com que o cursor se mova para o início da linha, assim, qualquer impressão depois de sobrescrever qualquer texto existente nessa linha até que um avanço de linha apareça.

Por exemplo:

#!/bin/bash

for i in {1..100}; do
    printf "We are now at %3d%%\r" "$i"
    sleep .1
done

printf "\nAll done.\n"

\r , ao usar printf resultam em <CR> ou Carriage Return.
\n , ao usar printf resultam em <LF> ou Line Feed.

    
por 06.06.2013 / 23:20
0

Em scripts de shell, o CR é um caractere comum, não um espaço em branco como em muitos outros idiomas. Essa linha DAY2="20130605"<Cr> define DAY2 para uma sequência de 9 caracteres, é equivalente a DAY2=$'20130605\r' . A linha echo é equivalente a echo $'This is yesterday date:20130605\rend' . O caractere CR ( $'\r' ) move o cursor para o início da linha, portanto ( ¡ indica a localização do cursor):

This is yesterday date:¡               #after printing up to date:
This is yesterday date:20130605¡       #after printing up to 20130605
¡This is yesterday date:20130605       #after printing the CR
end¡s is yesterday date:20130605       #after printing end

Remova o CR do script.

    
por 07.06.2013 / 02:56