Conflito entre minha definição de prompt e cat em zsh

6

Eu tenho um arquivo em um sistema de arquivos remoto que eu sei que tem uma pequena cadeia de texto (uma seqüência de números em uma única linha). Se eu abrir o arquivo em um editor de texto como nano ou Emacs, posso ver a string. Além disso, não tenho certeza se isso é relevante, mas ls informa que o arquivo tem 8 bytes *.

O curioso é que, se eu cat este arquivo, cat não informa nada.

No entanto, notei que, se eu adicionar um quebra de linha no final da linha, cat mostrará o conteúdo, o que está me confundindo.

Então, minhas perguntas são:

  • Por que isso acontece? Eu realmente preciso de um linebreak no final de cada linha para ter cat imprimir seu conteúdo? Este é o comportamento padrão para cat ? (em caso afirmativo, qual é o raciocínio por trás disso?)
  • Existe uma maneira de forçar cat a imprimir tudo em um arquivo, independentemente de eu ter ou não quebras de linha?

Atualização:

Com base nas respostas abaixo, achei que seria relevante postar como defini meu prompt. Estou no zsh e tenho as seguintes duas linhas no meu ~/.zshrc :

export PS1="%{$fg[white]%}%n%{$reset_color%} @ %{$fg[green]%}%m: %{$fg[yellow]%}%~ %{$reset_color%}%%
> "

Antes da definição do meu prompt, eu tenho as seguintes duas linhas que, acredito, permitem que eu use aliases de cores no shell:

autoload -U colors
colors

Reformulando a pergunta:

Com o acima em mente, como posso obter um linebreak no meu prompt, e ainda conseguir cat para imprimir um arquivo como o acima corretamente?

* Se eu touch um arquivo aleatório, ls informa que o arquivo tem apenas 0 bytes, presumo que o fato de ls informar que meu arquivo tem 8 bytes seja significativo. Não tenho certeza se isso é útil.

    
por Amelio Vazquez-Reina 06.10.2011 / 16:37

5 respostas

7

O Zsh gera um CR automaticamente antes do prompt para que o prompt possa ser iniciado em um local conhecido. Note que se você usasse um shell diferente de zsh, você obteria:

$ cat file
12345678$ _ <-- your prompt after the file contents

Aqui está uma entrada de perguntas frequentes sobre o problema: link

Os arquivos de texto devem terminar com uma nova linha por este e outros motivos - é incomum encontrar uma ferramenta para criá-los que não inclua um (exceto em um ambiente multi-plataforma - o bloco de notas do Windows não terminará arquivos uma nova linha por exemplo)

Se você puder tolerar uma linha extra em branco após a saída da maioria dos comandos (como no Windows) antes do prompt, tente adicionar uma nova linha no início do seu prompt:

export PS1="
%{$fg[white]%}%n%{$reset_color%} @ %{$fg[green]%}%m: %{$fg[yellow]%}%~ %{$reset_color%}%%
> "

E (talvez, pode até funcionar mesmo com isso ativado) desabilite a opção shell do prompt_cr. Você também pode tentar a opção "linha de espaços" do e-mail vinculado.

    
por 06.10.2011 / 18:07
4

Meu palpite é que seu prompt de shell está substituindo a linha que o gato escreveu. Tente o seguinte para verificar se é o caso:

cat file; echo

Dependendo do seu shell, você pode ajustar seus arquivos de configuração de alguma forma para garantir que isso nunca aconteça.

    
por 06.10.2011 / 16:47
3

Se você printf %q "$PS1" , mostra caracteres \r (retorno de carro)? Isso explicaria: cat produz alguma string sem uma nova linha, então, quando $PS1 é processado, ele retorna ao início da linha e sobrescreve o valor. Para verificar indiretamente se este é o caso, você pode tentar escrever um valor no arquivo que é maior que o seu prompt (ou apenas copiar o prompt para o início do arquivo), e ver se o cat output flui após o prompt.

    
por 06.10.2011 / 16:53
2

Se você fizer um echo $PS1 do seu shell, poderá verificar se há um \r em qualquer lugar na linha. Se sim, esse é o culpado.

Para corrigir o problema, você pode adicionar um \n ao início do seu prompt.

Se você só precisa colocá-lo em outro comando, pode fazê-lo sem medo de ser sequestrado. Para visualizá-lo na linha de comando, você também pode fazer cat file | less

    
por 06.10.2011 / 16:58
0

Eu defino meu PS1 assim:

PS1='\n\u@\h \w\n(\$\$='$$') \! \$ '

Então meu prompt parece com isso

...output of last command

glennj@machine ~
($$=29608) 1403 $

com uma linha em branco precedendo. Então, se houver saída sem uma nova linha, ainda é visível:

glennj@auds916 ~
($$=29608) 1403 $ printf hello
hello
glennj@auds916 ~
($$=29608) 1404 $
    
por 06.10.2011 / 20:04