logoalt Hacker News

A shell colon does nothing. Use it anyway

90 pointsby olexsmiryesterday at 1:33 PM29 commentsview on HN

Comments

zaptheimpalertoday at 5:28 AM

life is way too short to deal with this nightmare of a language and its 50000 footguns for anything longer than a 2 line script, especially in the age of LLMs. Just write a python/TS/any real language script instead. Bash is great for the command line, it should be limited to use there.

show 2 replies
kazinatortoday at 6:50 AM

> ( : < dataset.json ) && echo YES # is dataset.json readable?

The subshell execution parentheses and the colon are superfluous here, just:

   < dataset.json && echo YES
Redirections do not require a colon command to hang off of, and there is no need to fork a subshell to execute such a command.

> ( : >> result.json ) && echo YES # is result.json writable?

As a go-to idiom for a writability test, it gives me pause. If the file didn't exist, we created a zero-length one. That might be okay if we are going to write to it anyway as the next action.

If we are testing because we intend to overwrite it, why not just "> result.json" (which is by itself an idiom for truncating a file to zero length).

When would we every do this? Maybe before some command which takes the file name as a destination file argument rather than using output redirection, and which performs a lengthy computation before trying to open the file for writing. We can catch the permission error early.

I don't think I've ever coded such a test; normally you just do the operation that writes to the file and let that fail.

In POSIX C, there is a function access() for doing these kinds of tests. But it has a special purpose: it is meant to be used by a setuid root process to perform a permission test as if it were the real user/group (the one which elevated privilege to root). I.e. it's not can we do this operation, but should we do this operation (would we still be allowed, if we dropped privileges back to the original user).

show 1 reply
kevincoxyesterday at 1:52 PM

I am not a huge fan of most of these, but a few do seem useful.

    : "${1:?missing argument, aborting!}"
I wouldn't use this because I would want to give $1 a name for the rest of the script, so I would assign. But it can be a nice way to give a clear error for missing required environment variables.

Many of the others (like truncating files) are probably more clearly written with dedicated commands, but may come in useful if you are going to extreme lengths to avoid dependencies outside of the shell.

show 4 replies
jagadagatoday at 6:46 AM

Good to know, but looks less readable than `if` example.

Hamukotoday at 6:27 AM

Maybe it's just the fact that I woke up 10 minutes ago, but the readability of this looks awful. Even more than just usual shell scripts.

shevy-javatoday at 7:21 AM

This is an excellent article that helps people decide against writing shell scripts. I abandoned doing so shortly after I switched to linux. Since then I was also using ruby. I still do not understand why people would prefer shell scripts over ruby (or python). On systems without ruby or python, one may see a benefit in using shell scripts; other than that I fail to see why shell scripts are necessary.

Shell scripts simply suck for many reason. They are ugly, verbose, convoluted, outright stupid too such as argument passing into functions. Then there is straight up retarded stuff such as case/esac. Whoever came up with that was clearly an incompetent language designer.

PunchyHamstertoday at 6:44 AM

> Though.. what if I told you the above four lines could be replaced by just... one?

I'd reject the pull request. Bash is already bad as programming language (the goodness of language for long code is inversely proportional to how nice it is for shell one-liners), this is just turning "bad" into "line noise"

If your bash script takes more than one screen, rewrite it in Python, hell, rewrite it in Perl, even that's better

normie3000today at 5:55 AM

Prefer

``` if x then :; else something; fi ```

over

``` if ! x; then something; fi ```

Really? Colon is the appendix of the shell.

show 3 replies
jiveturkeyyesterday at 8:02 PM

the truncation is a poor example.

- it creates the file if it does not exist, not merely truncate. as a tutorial kind of blog post this incomplete description matters IMO.

- it would work the same without the colon (similar for default variable assignment examples). we generally strive not to have "extra" things, like useless use of cat.

- educationally it's useful to demonstrate that redirection, like parameter expansion, works before the command executes (the null command in this case), but the article doesn't explain that at all!

otherwise i <3 this article. some uses of colon i had never thought of or seen before. like file truncation, not sure i'd use them but it was cool to see them.

show 2 replies