Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Piping a command's output to ':' command

I am updating an old script and came across a pattern I am unfamiliar with:

# NOTE The | : always returns true so the <cmd> doesn't fail
<cmd> | :

I've only ever seen this pattern used in a fork bomb example. If someone were to ask me how to accomplish what is stated in the comment, I would have suggested:

<cmd> ||:

Before I chalk this up to a typo, has anyone seen this pattern and able to explain its use-case?

like image 240
aka Avatar asked Mar 09 '18 19:03

aka


1 Answers

It's a typo that also happens to have a similar effect. Differences:

  • cmd | : pipes cmd's stdout to :. Since : exits immediately, if cmd writes anything it will likely be hit with a SIGPIPE signal or EPIPE error, typically killing it.
  • cmd | : runs cmd in a subshell, nullifying environmental changes like var=value or cd /dir. Compare cd /tmp || : to cd /tmp | :.
  • cmd | : won't work if set -o pipefail is enabled.

Based on the comment it should be || :.

Technically, it's a race condition. cmd could write something before : exits, though it's unlikely. Or even more unlikely, if cmd wrote a lot it and filled up the pipe's buffer it would actually block until : exits, at which point its pending write() syscall would receive an EPIPE/SIGPIPE. You can simulate this with strace -e write yes | { sleep 0.1; :; }

like image 155
John Kugelman Avatar answered Sep 26 '22 18:09

John Kugelman