Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a file on a remote filesystem that I know has a short text string in it (a sequence of numbers in a single line). If I open the file on a text editor like nano or Emacs I can see the string. Also, not sure if this is relevant, but ls reports the file has 8 bytes*.

The odd thing is that if I cat this file, cat reports nothing.

However, I noticed that if I add a linebreak at the end of the line, cat then shows the contents, which is confusing me.

So my questions are:

  • Why does this happen? Do I really need a linebreak at the end of each line to have cat print its contents? Is this the default behavior for cat? (if so, what is the reasoning behind it?)
  • Is there a way to force cat to print everything in a file, regardless of whether or not I have linebreaks?

Update:

Based on the answers below, I thought it would be relevant to post how I defined my prompt. I'm on zsh, and I have the following two lines on my ~/.zshrc:

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

Before the definition of my prompt, I have the following two lines which I believe enable me to use color aliases in the shell:

autoload -U colors
colors

Rephrasing the question:

With the above in mind, how can I get a linebreak in my prompt, and still manage to get cat to print a file like the above correctly?


*If I touch a random file, ls reports the file has only 0 bytes, so I presume that the fact that ls reports that my file has 8 bytes is meaningful. Not sure if this is helpful though.

share|improve this question

5 Answers 5

up vote 6 down vote accepted

Zsh outputs a CR automatically before the prompt so the prompt can start at a known location. Note that if you used a shell other than zsh, you would get:

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

Here is a FAQ entry about the issue: http://zsh.sourceforge.net/FAQ/zshfaq03.html#l40

Text files are supposed to end with a newline for this and other reasons - it's unusual to find a tool for creating them that won't include one (except in a cross-platform environment - windows notepad won't end files in a newline for example)

If you can tolerate an extra blank line after most commands' output (as on windows) before the prompt, try adding a newline to the beginning of your prompt:

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

And (maybe, it might actually work even with it on) disable the prompt_cr shell option. You could also try the "line of spaces" option from the linked email.

share|improve this answer
    
Thanks @Random832, that explains it! Following up on your answer, I just found this entry in the official FAQ that explains a couple of alternative strategies to deal with this problem, including the ones you mentioned. –  user815423426 Oct 6 '11 at 16:49
1  
I've changed the link to the faq entry - the copy of the faq I found before didn't have the updated text about the line of spaces (and the PROMPT_SP option, which I knew existed but couldn't find anything about) –  Random832 Oct 6 '11 at 17:41

My guess is that your shell prompt is overriding the line cat wrote. Try the following to check whether it is the case:

cat file; echo

Depending on your shell, you can tweak your configuration files in some way to make sure this will never happen.

share|improve this answer
    
Interesting, if I type that, I then see the contents of my file. I'm on zsh. Not sure if this is related, but I defined my prompt with two lines and reads as follows: First line: export PS1="%{$fg[white]%}%n%{$reset_color%} @ %{$fg[green]%}%m: %{$fg[yellow]%}%~ %{$reset_color%}%% second line: > " –  user815423426 Oct 6 '11 at 14:55

If you printf %q "$PS1", does it show any \r (carriage return) characters? That would explain it: cat outputs some string without a newline, then as $PS1 is processed, it returns to the start of the line and proceeds to overwrite the value. To check indirectly whether this is the case, you can try to write a value in the file which is longer than your prompt (or just copy the prompt to the start of the file), and see if the cat output flows past the prompt.

share|improve this answer
    
Thanks! printf %q "$PS1" does not show any \r characters. All I get is: %\{[37m%\}%n%\{[00m%\}\ @\ %\{[32m%\}%m:\ %\{[33m%\}%\~\ %\{[00m%\}%%' on a single line, and then my prompt beneath it. I'll update the OP with the definition I have for my prompt, since there seems to be a connection with the way I have defined my prompt. –  user815423426 Oct 6 '11 at 14:58

If you do an echo $PS1 from your shell you can check to see if there is a \r anywhere in the line. If so that is the culprit.

To fix the issue you can add a \n to the beginning of your prompt.

If you just need to cat it to another command you can do so without fear of it being hijacked. To view it at the command line you can also do cat file | less

share|improve this answer

I define my PS1 like this:

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

So my prompt looks like this

...output of last command

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

with a blank line preceding. So if there is output without a trailing newline, it's still visible:

glennj@auds916 ~
($$=29608) 1403 $ printf hello
hello
glennj@auds916 ~
($$=29608) 1404 $
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.