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.

Attention please:

I am not asking how to make a file from the command line!


I have been using touch for making files for years without paying attention that its main purpose is something else. If one wants to create a file from command line there are so many possibilities:

touch foo.bar
> foo.bar
cat > foo.bar
echo -n > foo.bar
printf '' > foo.bar

And I'm sure there are more.

But the fact is, none of the commands above are actually designed for creating files. For example, man touch suggests this command is for changing file timestamps. Why doesn't an OS as complete as Unix (or Linux) have a command solely designed for creating files?

share|improve this question
27  
Why would you clutter the system to add a command to do something that can be done a dozen ways with tools that already exist? –  Michael Kohne Apr 10 at 11:49
3  
Why is there no command for reading files from/to streams/stdin/out? Everyone uses the command intended for con`cat`enation! –  SF. Apr 10 at 12:07
1  
@MichaelKohne, I see your point, with all due respect, I have a problem with it. With this approach there are many commands that are only cluttering the system. Why use more when less does more than what more do!? Or dir and ls. Albeit, I'm aware of compatibility issues. –  Pouya Apr 10 at 12:08
5  
more predates the creation of less. less has been created specifically to address shortcomings of more. more still exists for backward compatibility reasons. dir and ls are, for most intents and purposes, the same executable - they differ only in a handful of bytes. A new tool intended specifically for creating files would do less than existing tools, and as such it would be a regression, not an improvement like in the case of less vs more. –  lanzz Apr 10 at 13:46
1  
Plus we need to look at the legacy, Unix was created when each byte was counted. Why create a utility for a task that you can do with an already existing utility? –  Thomas Apr 11 at 1:52
show 6 more comments

3 Answers 3

up vote 28 down vote accepted

I would say because it's hardly ever necessary to create an empty file that you won't fill with content immediately on the command line or in shell scripting.

There is absolutely no benefit in creating a file first and then using I/O redirection to write to the file if you can do so in one step.

In those cases where you really want to create an empty file and leave it I'd argue that > "${file}" could not be briefer and more elegant.

TL;DR: It doesn't exist because creating empty files most often has no use, and in cases it has there are already a myriad of options available to achieve this goal.

On a side note, using touch only works if the file does not exist whereas options using redirection will always truncate the file, even if it exists (so technically, those solutions are not identical). > foo is the preferred method since it saves a fork and echo -n should be avoided in general since it's highly unportable.

share|improve this answer
1  
I found your point about creating the file and then using I/O tools, very solid. Thank you. –  Pouya Apr 10 at 12:10
1  
@FaheemMitha Yes (>>). I was referring to the examples given by OP using >. Appending would be quite useless if what you are after is creating files (or NOOP out if they exist). –  Adrian Frühwirth Apr 10 at 12:40
1  
Don't forget that noclobber has not to be set so that > will overwrite an existing file. –  Ouki Apr 10 at 13:23
1  
@Ouki AFAIK, setting that is not default behaviour and one could forget that it's set on one system and not another, potentially leading to trouble in the same way that creating an alias rm='rm -i' instead of alias rmi='rm -i' is a bad idea. –  snot waffle Apr 10 at 16:31
1  
@mikeserv, > .file, on a command line alone, will do that perfectly well without the :. –  Charles Duffy Apr 11 at 0:27
show 22 more comments

Adrian Frühwirth's answer is right on. I just wanted to add that there is actually a command specifically written to create files: mktemp.

NAME
       mktemp - create a temporary file or directory

SYNOPSIS
       mktemp [OPTION]... [TEMPLATE]

DESCRIPTION
       Create a temporary file or directory, safely, and print its name.  TEM‐
       PLATE must contain at least 3 consecutive 'X's in last  component.   If
       TEMPLATE is not specified, use tmp.XXXXXXXXXX, and --tmpdir is implied.
       Files are created u+rw, and directories  u+rwx,  minus  umask  restric‐
       tions.

Granted, mktemp's job is not to create a file with a specific name, it is simply to create a file. However, as you've already been told, there are so many more efficient and elegant ways to create files with a given name that providing a command for that would be pointless.

That said, you also have truncate and fallocate both of whose essential purpose is to create files. They simply have a more sophisticated approach. There will never be a simple program that does what > file does since there is no way it would be better than > file.

share|improve this answer
add comment

Most basic shell tools are not designed for any very specific purpose at all. Most basic shell tools are designed only to interact with others to achieve your purpose. Or maybe it should be said that most tools do only one very basic thing regardless of how they might be combined to achieve a goal.

: >./file

That creates an empty file. Or truncates an existing file as you will. You can:

set -o noclobber

to avoid any possibility of the latter case unless you:

: >|./file

You can get similar behavior to touch with:

: >>./file
: >>|./file

Except that : will not update a file's modtime because it isn't modified.

DEMO

mkdir test ; cd $_
touch touch.file 
: >null.file
echo >echo.file
ls -l

OUTPUT

-rw-r--r-- 1 mikeserv mikeserv 1 Apr 10 14:52 echo.file
-rw-r--r-- 1 mikeserv mikeserv 0 Apr 10 14:52 null.file
-rw-r--r-- 1 mikeserv mikeserv 0 Apr 10 14:52 touch.file

NOT TOUCH

: >>|./echo.file
ls -l 

OUTPUT

-rw-r--r-- 1 mikeserv mikeserv 1 Apr 10 14:52 echo.file
-rw-r--r-- 1 mikeserv mikeserv 0 Apr 10 14:52 null.file
-rw-r--r-- 1 mikeserv mikeserv 0 Apr 10 14:52 touch.file
share|improve this answer
    
By default, echo adds \n at the end of the line. Try echo -n >echo-n.file (size=0) and echo -e >echo-e.file (size=1) –  Thomas Apr 11 at 2:00
    
@Thomas 'A string to be written to standard output. If the first operand is -n, or if any of the operands contain a backslash ( '\' ) character, the results are implementation-defined. On XSI-conformant systems, if the first operand is -n, it shall be treated as a string, not an option. The following character sequences shall be recognized on XSI-conformant systems within any of the arguments...' pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html –  mikeserv Apr 11 at 2:04
    
Fair enough, thanks for the link, and my comment is not the point anyway –  Thomas Apr 11 at 2:25
1  
Yes indeed and sorry, I meant that my comment was missing the point of your answer anyway, sorry about that. –  Thomas Apr 11 at 2:30
1  
An illustration of the Unix tendency to generalize is the fact that the command to display the contents of a file is called cat. Why have a command to display one file, when you could make one command to concatenate multiple files to standard output? –  200_success Apr 11 at 2:54
show 2 more comments

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.