When you type into a shell, the shell recognizes some characters as commands. For example, the carriage return character (the character sent by the Enter key) causes the shell to execute the command. The tab character causes the shell to perform completion. When you paste something into the PuTTY terminal window, from the shell's point of view, that's the same thing as if you'd typed these characters. So at the point the tab character is pasted, the shell performs completion, it doesn't insert a tab.
The easiest way to copy a file without it being transformed would be to use PuTTY's companion program PSCP or PSFTP to copy the file. This is the simplest way conceptually, but it does have the overhead of running another program, authenticating, choosing a directory, etc.
If you want something inline, you can paste directly into cat
, rather than in a here document. Then you'd be pasting into the terminal's line editor, not into the shell's line editor. As the terminal's line editor is very primitive, only a few control characters have a special meaning there, not including tab. Press Ctrl+D at the beginning of a line to terminate the input.
[darkstar /]$ cat >text.txt
Paste
Ctrl+D
[darkstar /]$
I you want to transfer arbitrary data over a medium that interprets control characters, you can encode it into a form that uses only “tame” characters. Base64 is one; it doesn't use any control character and ignores whitespace and newlines. GNU coreutils, which is part of the basic installation on Linux and Cygwin, includes a base64
command. On the sender side, run base64 <file-to-decode
, e.g.
- On Windows: run
base64 c:/path/to/test.txt
from a Cygwin terminal
- Copy the output.
- In the shell in the PuTTY window, type `base64 -d >/tmp/test.txt and press Enter.
- Paste the output from
base64
.
- Press Ctrl+D.
For a pipe, the end of file is seen by the consumer(s) once all the producers have closed their file descriptor to the pipe and the consumer has read all the data.
So, in:
{
echo foo
echo bar
} | cat
cat
will see end-of-file as soon as the second echo
terminates and cat
has read both foo\n
and bar\n
. There's nothing more for you to do.
Things to bear in mind though is that if some of the commands on the left side of the pipe starts some background process, that background process will inherit a fd to the pipe (its stdout), so cat
will not see eof until that process also dies or closes its stdout. As in:
{
echo foo
sleep 10 &
echo bar
} | cat
You see cat
not returning before 10 seconds have passed.
Here, you may want to redirect sleep
's stdout to something else like /dev/null
if you don't want its (non)output to be fed to cat
:
{
echo foo
sleep 10 > /dev/null &
echo bar
} | cat
If you want the writing end of the pipe to be closed before the last command in the subshell left of the |
is run, you can close stdout or redirecting to that subshell in the middle of the subshell with exec
, like:
{
echo foo
exec > /dev/null
sleep 10
} | (cat; echo "cat is now gone")
However note that most shells will still wait for that subshell in addition to the cat
command. So while you'll see cat is now gone
straight away (after foo
is read), you'll still have to wait 10 seconds for the whole pipeline to finish. Of course, in that example above, it would make more sense to write it:
echo foo | cat
sleep 10
<<ANYTHING...content...ANYTHING
is a here-document, it's to make the stdin of command a file that contains the content. It wouldn't be useful there. \4
is byte that when read from a terminal makes data held by a terminal device be flushed to the application reading from it (and when there's no data, read()
returns 0 which means end-of-file). Again, not of any use here.
Best Answer
If the here document should only be added if none of it is present, you can use
grep
:To understand this, consider the following.
grep -F -q -f myPath/myFile{.append,}
is expanded by the shell togrep -F -q -f myPath/myFile.append myPath/myFile
.The
grep
command searchesmyPath/myFile
(the file to which the text should be added if necessary) for any fixed string (-F
) contained inmyPath/myFile.append
(the file containing the text to add), reading one pattern per line (-f
), and indicates whether it finds any only by its exit code, with no output (-q
).The result is then negated
!
, so that theif
block’sthen
part is only run ifgrep
doesn’t find anything.