In bash, touch
is an external binary, but echo
is a shell builtin:
$ type echo
echo is a shell builtin
$ type touch
touch is /usr/bin/touch
Since touch
is an external binary, and you invoke touch
once per file, the shell must create 300,000 instances of touch
, which takes a long time.
echo
, however, is a shell builtin, and the execution of shell builtins does not require forking at all. Instead, the current shell does all of the operations and no external processes are created; this is the reason why it is so much faster.
Here are two profiles of the shell's operations. You can see that a lot of time is spent cloning new processes when using touch
. Using /bin/echo
instead of the shell builtin should show a much more comparable result.
Using touch
$ strace -c -- bash -c 'for file in a{1..10000}; do touch "$file"; done'
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
56.20 0.030925 2 20000 10000 wait4
38.12 0.020972 2 10000 clone
4.67 0.002569 0 80006 rt_sigprocmask
0.71 0.000388 0 20008 rt_sigaction
0.27 0.000150 0 10000 rt_sigreturn
[...]
Using echo
$ strace -c -- bash -c 'for file in b{1..10000}; do echo >> "$file"; done'
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
34.32 0.000685 0 50000 fcntl
22.14 0.000442 0 10000 write
19.59 0.000391 0 10011 open
14.58 0.000291 0 20000 dup2
8.37 0.000167 0 20013 close
[...]
echo >> $file
will append a newline to$file
and thus modify it. I assume it will be the same for OS/X. If you do not want that, useecho -n >> $file
.touch `find . -name "*.xml"`
be even faster than both of the above?>>$file
touch
so many times at all?find . -name '*.xml' -print0 | xargs -0 touch
invokestouch
much fewer times (possibly only once). Works on Linux, should work on OS X.