Understanding the Purpose of /usr/bin/[ in Linux: A Technical Deep Dive


1 views

While auditing my CentOS servers, I stumbled upon an intriguing ELF binary at /usr/bin/[. At first glance, this might look like someone tried to hide a malicious program with a bracket filename - a common technique in security incidents. However, further investigation revealed this is actually a legitimate part of core Linux utilities.

The [ command (yes, it's literally named a single left bracket) is equivalent to the test command. It's a built-in shell command used for conditional expressions in shell scripting, but also exists as a standalone binary for POSIX compliance.


# Example usage in bash:
if [ -f "/etc/passwd" ]; then
    echo "File exists"
fi

This unusual naming convention dates back to early Unix systems. The [ command requires a matching ] as its last argument - hence the bracket naming. This maintains compatibility with shell scripts while following POSIX standards.

While functionally identical, there are subtle behavioral differences:


# Using the test command
test -f file.txt && echo "Exists"

# Using the [ command
[ -f file.txt ] && echo "Exists"  # Note the required closing ]

The existence of /usr/bin/[ isn't inherently suspicious, but it's worth checking:


# Verify the binary's integrity
$ rpm -Vf /usr/bin/[
$ md5sum /usr/bin/[
$ ls -l /usr/bin/[

Legitimate instances should be symlinked to /usr/bin/test in most modern distributions.

Shell built-in versions are generally preferred as they avoid spawning a new process:


# Time comparison
$ time for i in {1..1000}; do /usr/bin/[ -f /etc/passwd ]; done
$ time for i in {1..1000}; do [ -f /etc/passwd ]; done

Common problems include:

  • Missing closing bracket (syntax error)
  • Spacing requirements around brackets
  • Different behavior between shells

# Correct:
[ "$var" = "value" ]

# Incorrect:
[$var="value"]

During routine system exploration, many UNIX/Linux administrators stumble upon a curious binary: /usr/bin/[. At first glance, its name suggests either a malicious file hiding in plain sight or some system artifact. However, this is actually a legitimate component of coreutils.

The [ command is essentially equivalent to the test command, just with different syntax requirements. The closing bracket is literally part of the command syntax. This explains why you'll often see shell scripts using constructs like:

if [ -f "/path/to/file" ]; then
    echo "File exists"
fi

In this example, [ isn't special shell syntax - it's actually invoking /usr/bin/[ or its built-in shell equivalent.

Key facts about this command:

  • Requires a closing ] as its last argument
  • Returns exit status 0 for true, 1 for false
  • Available as both shell built-in and standalone binary
  • Part of POSIX specification since early UNIX versions

Here are some common use cases with shell scripts:

# File tests
[ -f "/etc/passwd" ] && echo "Found password file"

# String comparisons
[ "$USER" = "root" ] && echo "Running as admin"

# Numeric comparisons
[ $COUNT -gt 10 ] && echo "Count exceeds threshold"

# Combine tests
[ -d "/backups" -a -w "/backups" ] && cp important.txt /backups/

The standalone /usr/bin/[ exists primarily for:

  • Portability - ensures consistent behavior across different shells
  • POSIX compliance - maintains standardization
  • Edge cases - handles situations where shell built-ins might not be available

While the command itself isn't malicious, its unusual name makes it noteworthy:

  • Check file integrity: ls -l /usr/bin/[ should show root ownership
  • Verify checksum: sha256sum /usr/bin/[ should match other system binaries
  • Compare with shell built-in: type -a [ should show both versions

For more complex conditionals, consider combining with other test operators:

# Check multiple conditions
[ -n "$VAR" -a "${VAR:0:1}" = "/" ] || { echo "Invalid path"; exit 1; }

# Modern shells prefer [[ ]] which has more features
[[ $FILE == *.txt && -s $FILE ]] && process_text_file "$FILE"

Understanding this fundamental command helps in writing robust shell scripts and troubleshooting system behaviors.