Skip to main content


In today's #Linux #shell adventures, did you know that [ is an executable ELF binary provided by coreutils? There's a /usr/bin/[ program in the $PATH on most Linux systems.

Check it out:
which [

This entry was edited (7 months ago)
in reply to Scott Williams 🐧

@Scott Williams 🐧 ...which is usually a symlink to /usr/bin/test, if I'm not mistaken.

Edit: It appears this may no longer be the case.

in reply to Jonathan Lamothe

@me It's not a symlink on Fedora, at least. It's an ELF executable. It very well might be a wrapper on test at the code level, though.
in reply to Scott Williams 🐧

@Scott Williams 🐧 Ah, my source on this was a book I purchased in the 90s. I may well be misremembering, or things may have changed since then.
in reply to Jonathan Lamothe

@alilly OK, so I dove into the rabbit hole and you're half right. In an interactive shell, the coreutils ELF binary is invoked, but in a *bash script*, the bash built-in gets invoked instead, which is the alias for the test bash built-in. Similarly, there is a coreutils for test as well and it behaves the same way.
This entry was edited (7 months ago)
in reply to Athena L.M.

@alilly @me Something, something, posix, something.

On that note `man posix` tells you about a Perl module.

in reply to Athena L.M.

@alilly @me So, I did this, and it's not calling test at all. It is calling libc and locale when it generates an error message. It seems like a basic and straightforward C program AFAICT.
in reply to Jonathan Lamothe

@Jonathan Lamothe @Scott Williams 🐧 On my system both are their own binaries, and both seem to be different (vbindiff shows differences), but they do the same thing
in reply to Scott Williams 🐧

Yeah, this one really made me do a double take when I noticed it many years down the road. Another one of those UNIX things that makes you think, “wait really??”

Then you remember other weird UNIX things and think, “yeah, well I guess I’m not that surprised at this particular weirdness.”

in reply to Scott Williams 🐧

far less stuff is builtins than I once thought, would you believe I was surprised to discover ls isn't a builtin?
in reply to Athena L.M.

@alilly Writing my #qbsh side project has given me a new appreciation for Linux internals, coreutils, and built-ins - and not to mention the pipe layer between them all. It's a silly project, but I've definitely learned some useful things along the way.
in reply to Scott Williams 🐧

yes, but bash usually spoils the fun by making it a shell builtin too. So `[ --version` doesn't work, but `/usr/bin/[ --version` does.
in reply to aburka 🫣

@aburka Ah, you're right. [ is a built-in for test, according to the bash info page.
in reply to Scott Williams 🐧

@aburka But according to strace, the /usr/bin/[ is used when it's at the start of the command. I'm guessing that the bash built-in kicks in following if.
in reply to Scott Williams 🐧

@aburka OK, I think I've figured it out. When running in an interactive shell, the coreutils version is invoked.

When running in a script, the bash built-in is invoked regardless of whether at the beginning of the line or followed by if.

This website uses cookies. If you continue browsing this website, you agree to the usage of cookies.