13

I am new to Linux. When I create a new file .gitignore under current directory using bash, I found out that I can do:

> .gitignore

or

touch .gitignore

It seems they do the same thing. When I check the manual for touch, it says change timestamp for the current file, but there is no manual for >. So can someone explain what can > do and is there any difference in using these two commands under this context? Thanks.

muru
  • 193,181
  • 53
  • 473
  • 722
  • 1
    I'm curious where you learned to use '>' as a file generator without learning its intended use – forresthopkinsa Feb 08 '17 at 00:20
  • 1
    You will find redirection documented in the Bash manual. At the command line, enter the command `man bash`. It's a long document and will take days or even weeks to understand well, but it's well worth going through if you want to learn Bash thoroughly. – Paddy Landau Feb 14 '17 at 12:40

2 Answers2

21

> is the shell redirection operator. See What's is the difference between ">" and ">>" in shell command? and When should I use < or <() or << and > or >()? It is primarily used to redirect the output of a command to a file. If the file doesn't exist, the shell creates it. If it exists, the shell truncates it (empties it). With just > file, there is no command, so the shell creates a file, but no output is sent to it, so the net effect is the creation of an empty file, or emptying an existing file.

touch is an external command that creates a file, or updates the timestamp, as you already know. With touch, the file contents are not lost, if it exists, unlike with >.

The behaviour of > depends on the shell. In bash, dash, and most shells, > foo will work as you expect. In zsh, by default, > foo works like cat > foo - zsh waits for you type in input.

muru
  • 193,181
  • 53
  • 473
  • 722
  • 10
    The key point here is that there is no practical difference between `>> file` and `touch file` but if `file` does not exist, there's a big difference between both of them and `> file` (in that the previous contents of `file` are lost). That, plus the inconsistent behavior of zsh means `touch file` is the "safest" and therefore should be memorized as The Right Way To Do It. – Monty Harder Feb 07 '17 at 20:11
1

Here is an interesting comparison:

$ cat redirect.sh touch.sh sed.sh awk.sh cp.sh truncate.sh tee.sh vi.sh
> redirect.txt
touch touch.txt
sed 'w sed.txt' /dev/null
awk 'BEGIN {printf > "awk.txt"}'
cp /dev/null cp.txt
truncate -s0 truncate.txt
tee tee.txt </dev/null
vi -esc 'wq vi.txt'

Result:

$ strace dash redirect.sh | wc -l
387

$ strace dash touch.sh | wc -l
667

$ strace dash sed.sh | wc -l
698

$ strace dash awk.sh | wc -l
714

$ strace dash cp.sh | wc -l
786

$ strace dash truncate.sh | wc -l
1004

$ strace dash tee.sh | wc -l
1103

$ strace dash vi.sh | wc -l
1472
muru
  • 193,181
  • 53
  • 473
  • 722
Zombo
  • 1
  • 21
  • 21
  • 1
    While the comparison might be interesting, I do not really see what you want me to see here. Can you explain what you are going for? I guess it's different ways to write stuff into files, but I find it a little confusing like this. Might be my lack of coffee though. – m00am Feb 08 '17 at 08:12
  • @m00am what is shown here is effectively 8 different ways to create a file. `strace` is supposed to show the system calls that are being executed, and `> file.txt` method is shown to be the least amount of system calls executed, which really isn't all that surprising - the more complex a tool is, the more complex its syscalls are. The issue with the examples shown , however is that `strace` writes to `stderr` stream by default, and in this answer Steven uses pipe to read only `stderr`, so I'm slightly confused how he counted the lines using `|` pipe and not `|&` – Sergiy Kolodyazhnyy Feb 08 '17 at 09:19
  • And on Ubuntu 16.04, using `|&`, as @Serg mentions, I get counts about a fifth of the ones here ... except for the `vi` case, where I get about the same value – muru Feb 09 '17 at 03:37
  • WSL? Woah... I didn't think WSL would add *that* many system calls for what it does. – muru Feb 09 '17 at 03:39
  • @muru Cygwin - WSL is not ready yet http://stackoverflow.com/a/40370009 – Zombo Feb 09 '17 at 03:40