Replace file with hard link to /dev/null

14,142

Solution 1

# cp -a /dev/null log.txt

This copies your null device with the right major and minor dev numbers to log.txt so you have another null.

Devices are not known by name at all in the kernel but rather by their major and minor numbers. Since I don't know what OS you have I found it convenient to just copy the numbers from where we already know they are. If you make it with the wrong major and minor numbers, you would most likely have made some other device, perhaps a disk or something else you don't want writing to.

Solution 2

You can make a symbolic link to /dev/null and you don't need to be root:

ln -s /dev/null log.txt

Solution 3

The other answers here will probably work. In particular, the symlink solution is probably going to be the easiest solution. I offer this mainly for completeness.

The solutions involing mknod (or cp -a) become problematic if the filesystem containing the file doesn't support devices (e.g., it was mounted with the nodev option, for example). And of course, hard links across filesystems simply won't work.

An alternative to hard links or creating new devices nodes is to use bind mounts, which let you mount a file or directory from one part of your filesystem tree onto another. So, for example, you can run:

mount -o bind /dev/null /path/to/log.txt

This acts a lot like a hard link, but:

  • It can operate across filesystems (because it's not based on filesystem inodes like a hard link)
  • It works on read-only filesystems (because you're not actually modifying the filesystem)

For a complete example:

bash-4.3# ls -l /var/log/boot.log
-rw-r--r--. 1 root root 7436 Dec 19 10:00 /var/log/boot.log
bash-4.3# mount -o bind /dev/null /var/log/boot.log
bash-4.3# ls -l /var/log/boot.log
crw-rw-rw-. 1 root root 1, 3 Dec 19 09:58 /var/log/boot.log
bash-4.3# echo words words words > /var/log/boot.log
bash-4.3# ls -l /var/log/boot.log
crw-rw-rw-. 1 root root 1, 3 Dec 19 09:58 /var/log/boot.log

Solution 4

It depends critically on HOW the application handles log.txt.

If the application just opens the existing file and writes to it then as described in other answers you can symlink it to /dev/null, symlink it somewhere else, hardlink it somewhere else (though hardlinks can't be cross filesystem so there isn't a lot of point in this) create a copy of the /dev/null device node there etc.

OTOH if the application deletes and recreates log.txt none of that will work. You could symlink the whole directory somewhere else to redirect the writes to a different filesystem but thats about it and you would have to deal with other stuff in the directory.

I guess if you really wanted you could create a custom overlay filesystem that passed most operations right through while throwing away any attempts to create a file called log.txt.

Solution 5

Well, one ungraceful method with named pipe:

# create a named pipe
mkfifo /path/to/log.txt
# read contents from the pipe and redirect them to /dev/null
cat /path/to/log.txt > /dev/null

you almost can do anything with the dumped log, such as filter or send over nc.

Share:
14,142

Related videos on Youtube

MALON
Author by

MALON

Updated on September 18, 2022

Comments

  • MALON
    MALON almost 2 years

    I'm running an application that writes to log.txt. The app was updated to a new version, making the supported plugins no longer compatible. It forces an enormous amount of errors into log.txt and does not seem to support writing to a different log file.

    How can I write them to a different log?

    I've considered replacing log.txt with a hard link (application can't tell the difference right?) Or a hard link that points to /dev/null. What are my options?

    • user168715
      user168715 over 7 years
      You can't just chmod -w log.txt?
  • mklement0
    mklement0 over 7 years
    It is worth noting that this command requires sudo (or running as the root user). Please explain (in your answer) what you mean by "the right major and minor dev numbers".
  • MALON
    MALON over 7 years
    This worked really well for me, thank you!
  • mklement0
    mklement0 over 7 years
    (I'm not the OP.) I appreciate the update, but I'm still confused about how "major and minor numbers" relate to file path /dev/null, as used in your command. And, I think it would help future readers to note in your answer that sudo is required.
  • Joshua
    Joshua over 7 years
    @mklement0: bash: sudo: command not found
  • mklement0
    mklement0 over 7 years
    @wallyk: Thanks, that's indeed good to know. But my point is: How does come into play with respect to cp -a /dev/null log.txt and my comments?
  • MALON
    MALON over 7 years
    For what it's worth, I did tag my OS in the post. Ubuntu 14.04 x64
  • mklement0
    mklement0 over 7 years
    @MALON: Indeed you did, and on Ubuntu 14.04 you do need sudo to perform this command, unless you happen to be running as user root (which is generally discouraged). Using sudo (or running as root) to create a hard link (this answer) or a symlink (@V.Michel's answer) may be the right solution after all, if the file must be placed in a location that any user account can write to, but the point is: do note that requirement explicitly.
  • mklement0
    mklement0 over 7 years
    P.S.: I know see that the major, minor comments probably relate to a comment on the question recommending use of mknod. Do note that comments generally receive little attention, so someone reading the question only and then your answer may be confused (as was I; also note that most people are never exposed to concepts such as major and minor device numbers).
  • reinierpost
    reinierpost over 7 years
    But it only works on systems that have a bind mount. (Such as modern Linux.)
  • mlv
    mlv over 7 years
    I wouldn't recommend this. Unless you have intimate knowledge of your device major/minor numbers, looking at this later can be very confusing. Also, as stated above, you have to be root to do it, and probably for good reason. For example, if you tried to create your log.txt version of /dev/null but you used 1 1 instead of 1 3, you'd cause some extremely serious problems with your system. Far, far better is to just use a symbolic link. ln -s /dev/null log.txt You don't need to be root, and you don't have to memorize major/minor dev numbers to know what's happening.
  • ygreaney
    ygreaney over 7 years
    This also has the advantage of being self-documenting, in that ls -l log.txt would show that it's a symlink to /dev/null, rather than relying on knowing that e.g. "1, 3" is somehow significant.
  • ygreaney
    ygreaney over 7 years
    A log file wouldn't belong in a read-only filesystem anyway.
  • Joshua
    Joshua over 6 years
    @hobbs: Turns out nodev + nosuid didn't work so well as intended. The man page even outright calls it out as doesn't work if setuidperl is installed on the system. Maybe someday they'll fix that and nodev + nosuid provide real security for mounting removable filesystems without pinning the type again.
  • Marco Marsala
    Marco Marsala over 5 years
    chattr +i log.txt the first time and the application won’t delete the file anymore.
  • Marco Marsala
    Marco Marsala over 5 years
    If cat process is killed or crash, the login program will hang when the pipe is full.
  • Kusalananda
    Kusalananda over 4 years
    This adds nothing to what others have already said.
  • Freedo
    Freedo over 3 years
    This makes the log file be owned by root :(
  • Joshua
    Joshua over 3 years
    @Freedo: chown is your friend. If you want your private copy of null to be owned by somebody else, nothing's stopping you.