Whenever I open a bash terminal, the error code 1 is returned:
Last login: Tue Jan 15 16:19:53 on ttys000
spam@moss:~ $ echo $?
1
I found this is caused by last line of code in my .bash_profile
:
test -f $HOME/.debug && export profile_bash_profile='.bash_profile' || return 0
If I remove this line, then the error code 0 is returned. I don't understand how this line could cause any problem, because I can source .bash_profile
with the error code 0:
spam@moss:~ $ source .bash_profile
spam@moss:~ $ echo $?
0
Update:
Does anyone one know how Mac load ~/.bash_profile? I doubt Mac sources it when a login shell is launched. It seems the return
command doesn't run as expected – when I put return 5
as the last line of ~/.bash_profile
and launch a login shell, it does not return error code 5 (and I am sure ~/.bash_profile
is the last script loaded).
Best Answer
Note that what happens when using
return
outside a function without havingsource
d the script (e.g.return
ing from.bash_profile
) is undocumented inman bash
.The difference is in how the return code of a script or function is recorded internally in
bash
. If youreturn
a value, that value is assigned the return code of the calling code, e.g. the function call you return from, or thesource
command. As there is no such caller when returning from.bash_profile
during shell initialization, that value is simply discarded. What you're accessing as$?
is the return code of the preceding statement.Using Apple's bash-86.1 as reference:
If you
source
a script, its contents are parsed and executed, until areturn
statement is encountered. Its return value is recorded separately, and it's the responsibility of the caller (execute_command_internal
inbash-3.2/execute_cmd.c
) to assign its value to the variable holding the last exit code:last_command_exit_value
.If it's called as a startup script, it is loaded via a call to
maybe_execute_file
in therun_startup_files
function inbash/shell.c
. It's not regular command execution: While the contents of the file are executed properly, including the finalreturn
, nobody cares about the actual value you're returning. It is simply discarded.So, what behavior are you seeing here? Essentially the same as if you'd called
return
without argument: Likereturn
simply returned the return code of the command preceding it, which, in your case, is the failed test.How to get the desired behavior? Since you can't
exit
from.bash_profile
without quitting the shell, you need to make sure the command immediately preceding it produces the desired return code, in this case: