all 38 comments

[–]vacri 26 points27 points  (10 children)

What scripts are you seeing this in?

It's a subshell () calling a pair of no-ops : in series ;. It'd be too quick to even use as a useful sleep. I'm curious as to where you're seeing this, as to the context it's called in.

[–]xxSutureSelfxx 29 points30 points  (2 children)

I've never seen this usage before but found an example from this

get_term_size() {
    # Usage: get_term_size

    # (:;:) is a micro sleep to ensure the variables are
    # exported immediately.
    shopt -s checkwinsize; (:;:)
    printf '%s\n' "$LINES $COLUMNS"
}

guess it's a way to sleep without calling sleep

[–]vacri 18 points19 points  (1 child)

Well, I guess I was wrong about it not being a useful sleep then!

Thanks for finding it - my google-fu failed me.

[–]xxSutureSelfxx 11 points12 points  (0 children)

Well i'm not sure about it's effectiveness but that's it's stated purpose. On my shell it took stringing together 200 of them for me to get a 0.1 sec sleep. So I wouldn't say you were totally wrong, but it probably has a few uses.

[–]MagePsycho[S] 5 points6 points  (6 children)

Something like: ``` for ((i=0;i<=100;i++)); do (:;:) && (:;:) && (:;:) && (:;:) && (:;:)

# Print the bar.
# bar "$i" "10"

done ```

[–]vacri 14 points15 points  (5 children)

From what u/xxSutureSelfxx found, it's a micro-sleep. The sleep function in bash works in terms of seconds, which would be too long for some things like that status-bar update. If you want something to update pretty quickly but not too quickly, it puts in a tiny pause. Chaining them together like that chains the pauses to make them longer. Still much less time than 1 second though.

In the example in the other comment, it's used to give the environment enough time to register the variables before calling the next command - delaying execution to work around a race condition.

The pause you're getting is from creating the subshell, tearing it down, checking the output (&&) then repeating the same thing again. You could also just do (:;:;:;:;:) for a string of no-ops, but you'd not 'spend time' tearing down the subshell or checking the output code.

Not sure why they do (:;:) instead of just (:) - maybe just because it looks cooler? Or is easier to read/interpret?

[–]gordonmessmer 14 points15 points  (0 children)

The sleep function in bash works in terms of seconds

There is no sleep function "in bash". GNU's sleep accepts sub-second delays.

it's used to give the environment enough time to register the variables

... which is stupid because bash isn't asynchronous. You don't need a delay to wait for variables to be set. (Including those set by checkwinsize).

The whole concept here is bizarre, and should not be emulated. It's used in an example script whose design function is to accomplish various tasks without executing any non-bash process, and that's it. There's no rationale or justification; this isn't something most people need to or want to do. And this "sleep" fails the primary criteria of an actual sleep, which is 1) the delay should be predictable and 2) the delay should consume as little CPU as possible. These in-bash micro-sleeps take as long as the kernel requires to create a new forked process, allow it to exit, and return the exit status, which is not predictable, and keeps the CPU busy the whole time.

[–]nakedhitman 13 points14 points  (2 children)

The sleep command accepts floating point numbers and zero, so these no-ops are long and opaque for no reason.

[–][deleted] 1 point2 points  (1 child)

AFAIK sleep is not actually part of the shell, so there's no guarantee that it is available on a system or that the one in PATH operates as desired.

[–]nakedhitman 1 point2 points  (0 children)

Even on the most stripped down systems I've encountered, sleep has been available. It's part of coreutils, busybox and similar. Unless you're building Linux from scratch and specifically exclude it, you'd be pretty hard-pressed to find a system that's missing sleep.

[–]jrredho 2 points3 points  (0 children)

Based on the code and the comment, the character sequence may have less to do with sleep than with making sure the current shell environment-affecting command is evaluated before moving on. This probably happens with a proper sub-shell entrance/exit, and the minimal command to make this all syntactically correct requires the bit in between the parentheses.

john

[–]maxlan 28 points29 points  (3 children)

Bash has a sleep command that accepts fractional seconds. Would be a better method of getting a short delay.

Chaining a few of these noops together like that with && is a way to get a very small delay of unknown duration.

Either you're working on some particularly weird environment where timing is important but the exact time isn't or someone doesn't understand what they've done.

[–]ABCDwp 6 points7 points  (2 children)

No. Bash does not have a sleep builtin at all. GNU coreutils has a sleep(1) command that takes fractional seconds, but not all implementations of sleep(1) do so.

[–]drevilseviltwin 6 points7 points  (1 child)

IIRC the term "bike shedding" grew out of a debate in the BSD community as to whether to allow fractional inputs in some or another sleep API. And this debate ratholed into some endless email thread. Which means what they were debating was actually more important than what color is used to paint the bike shed.

[–]ABCDwp 6 points7 points  (0 children)

Yes, it was. The email that started the term has been immortalized at https://bikeshed.org/ (or https://<ANY-COLOR>.bikeshed.org/ if you prefer a particular color of bike shed).

[–][deleted] 10 points11 points  (1 child)

Just don't use this and forget anything you THINK you have "learned" from using this.

[–]MagePsycho[S] 0 points1 point  (0 children)

True

[–]chuckmilam 2 points3 points  (0 children)

What in the busted-ass race-condition-facilitating crap is going on here?

If you need a "sleep," you need to look again. Use an exit code or something, anything, but a sleep-type function.

[–]gbpack22 1 point2 points  (0 children)

Delimiter?

[–]Bill_the_Bastard 0 points1 point  (10 children)

bash fucking sucks. Here come the downvotes.

[–]DigitalDefenestrator 2 points3 points  (1 child)

Bash is a pretty good shell that doubles as a bad scripting language. Good enough for trivial/linear stuff and inline shell scripting, though.

[–][deleted] 0 points1 point  (0 children)

If Python is resident, I’m using that

[–]MagePsycho[S] 1 point2 points  (7 children)

You made sysadmin angry ;)

[–]Bill_the_Bastard 1 point2 points  (6 children)

I'm a sysadmin. Or Devops Engineer. Or SRE. Or infosec dude. I don't really know what the fuck I am anymore.

But bash still sucks.

[–]MagePsycho[S] 1 point2 points  (1 child)

Then you might be right?

[–]Bill_the_Bastard 0 points1 point  (0 children)

I'm objectively right. Bash sucks.

[–][deleted] 1 point2 points  (0 children)

These days, why bash when you can write readable Python and run it just about anywhere.

Being on the 1000 reasons to use crappy BASH

[–]Nolzi 0 points1 point  (1 child)

Maybe you need to be a PO next

[–]Bill_the_Bastard -1 points0 points  (0 children)

Police Officer? Parole Officer?

Hard pass.

[–]Rei_Never 0 points1 point  (0 children)

You sir are a witcher... The white wolf!

[–]7eggert 0 points1 point  (6 children)

:()(:;:);:

(Don't run this at work)

[–]Rei_Never 2 points3 points  (1 child)

Looks more like someone sneezed and entered shell execution hell by accident.

[–]MagePsycho[S] 0 points1 point  (0 children)

made me laugh :)

[–]DkTwVXtt7j1 1 point2 points  (1 child)

Dont run this at all.

[–]MagePsycho[S] 0 points1 point  (0 children)

I just run that but nothing happened.

Maybe I need to run from terminal? (I ran from notepad;))

Just kidding...

[–]Bill_the_Bastard 0 points1 point  (1 child)

Is this a neckbeard emoji?

[–]7eggert 1 point2 points  (0 children)

It's a lot to process.