Piping a command's output to ':' command
Asked Answered
C

2

9

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?

Carhart answered 9/3, 2018 at 19:25 Comment(0)
M
8

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; :; }

Massenet answered 9/3, 2018 at 19:36 Comment(0)
F
-1

I think it's a way to suppress the standard output of the command, it would the equivalent to:

<cmd> > /dev/null

I see it usefull in scripts where you don't want to show the output of cmd

Fox answered 9/3, 2018 at 19:31 Comment(2)
Not equivalent. | : will cause failure when the program on the left-hand side tries to write to its stdout after the copy of :/true has already exited, whereas > /dev/null will work for any arbitrary amount of content.Sporulate
@CharlesDuffy so, in a few words, if the output of cmd is too big it will produce an error?Fox

© 2022 - 2024 — McMap. All rights reserved.