13

I have a file in $HOME/bin (before you ask, yes, it is in my path) called test which I've confirmed can be executed fine when I run it with the full path to the file. However, I get a really weird issue when I don't run it this way. When I just run test in the terminal, it doesn't do anything and returns immediately. I know that this isn't an issue of finding the file for several reasons:

  1. There is no error message. Normally if the file can't be found or can't be executed a message will be printed out saying so.

  2. Running which test still returns the correct file path.

  3. Probably the weirdest of all - the script works fine when run through strace. I tried using strace to see if I could figure out what was going on but when I ran it with strace, it worked as expected with 0 issues.

1 Answers1

45

test is an unfortunate name to use, it's the standard utility for conditional tests. (It's actually the same command as the [ in if [ ... ], it just looks like a syntactical thing, but is really just a normal command.)

test is also builtin in e.g. Bash, so running just test never looks up your binary from the path.

bash$ help test | head
test: test [expr]
    Evaluate conditional expression.

    Exits with a status of 0 (true) or 1 (false) depending on
    the evaluation of EXPR.  Expressions may be unary or binary.  
    [...]

test with no arguments just returns 1 (false).

Running strace test doesn't involve the shell builtin, since strace doesn't implement any utilities itself. It just uses what it finds in your PATH. Note that you probably have the standard test in /bin/test or /usr/bin/test, so if that would be first in PATH, strace would run run that.

On my Bash, which is also an external command, so it doesn't have an idea about builtins either. On the other hand, the type command is builtin to the shell, and type test would show that test is a shell builtin.

See also: Why not use "which"? What to use then?

ilkkachu
  • 138,973