Jesse Jackson Jesse Jackson - 1 year ago 82
Bash Question

bash: ????: command not found

(I'm using bash 3.2 in the Terminal app on OS X 10.11.4.)

I have this line in my

alias ll='ls -alFh'

I ran
echo ll > test && chmod +x test
to create a
executable. Below are the results of running multiple commands, their exit codes (via
echo $?
), and

  1. test

    exit code 1

    produces no stdout

  2. ./test

    exit code 127

    ./test: line 1: ll: command not found

  3. . test

    exit code 127

    -bash: ????: command not found

  4. . ./test

    exit code 0

    produces identical result to manually running

I understand that exit code 1 is a generic error and that exit code 127 means the shell can't find the command. Will someone please explain what is happening in each of these cases and why, including a description of the stdout? I am especially confused at #3 with the

Answer Source

First you run:

echo ll > test && chmod +x test

then these cases.

Case 3:

When you execute:

. test

it is equivalent of:

source test

source is a shell builtin that tells the shell to read the given script file and execute the commands in the current shell environment. However since **current path or . is not in your pathit findstestusingPATHenvironment variable which is/bin/test`.

/bin/test is not really a script file that can be read/executed by source it ends up reading binary file and errors out since that file is a binary file, not an ascii text file and errors out writing:

????: command not found

You will get same behavior when you run source date or source ls as these are all binary files.

Case 1:

You are executing shell builtin test without any arguments that makes it exits with exit value: 1

Case 2:

When you run ./test it attempts to run ll and alias is not available in spawned sub-shell hence it cannot find alias ll. Due to that fact it exits with exit value: 127 with ./test: line 1: ll: command not found error on stderr.

Case 4:

. ./test is same as source ./test that run in current shell only. Therefore it is able to find alias you've set earlier for ll hence it runs aliased command ls -alFh and exits with 0