Checking if current file is being sourced is being reversed if $? is 0

Multi tool use
Multi tool use
The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


Checking if current file is being sourced is being reversed if $? is 0



I know the title is a bit weird, but I'm not sure how to better word it.



I'm using $(return &> /dev/null) to detect if a file is sourced or not.


$(return &> /dev/null)



I know that this method is not 100% reliable, but it has worked for me without issues before now. I've figured out how to work around the problem, but I can't figure out why this is happening.



I've tried this on three different systems and had the same results:


Redhat 6.9; $BASH_VERSION=4.1.2(1)-release
Mint 18.2; $BASH_VERSION=4.3.48(1)-release
Arch; $BASE_VERSION=4.4.23(1)-release



If $? is 1 (false) when $(return &> /dev/null) the return code is reversed.


$?


$(return &> /dev/null)


$ hr | cat test_0source - test_0source.sh; hr; ./test_0source
#!/bin/bash
# test_0source

false
test_0source.sh

false
source test_0source.sh

true
test_0source.sh

true
source test_0source.sh
========================================
#!/bin/bash
# test_0source.sh

# shellcheck disable=SC2091
$(return &> /dev/null)
echo "$?"
========================================
1
1
1
0



I expected to be seeing


1
0
1
0



My workaround is to add true right before the return check. While this gives me the correct results, adding false instead of true cause the return check to always return 1.


true


return


false


true


return



I realize I'm missing something basic here, but I'm not seeing it. Why is this doing this?



Edit: I had an incorrect value for $? in my initial explanation above.





May I interest you in an alternative method? [[ "${BASH_SOURCE}" = ${0} ]] evaluates to 0 if file is not source and 1 if it is (test for not equal if you prefer it the other way around). Should run on bash pretty much anywhere.
– Ondrej K.
30 mins ago


[[ "${BASH_SOURCE}" = ${0} ]]


0


1


bash




1 Answer
1



What you are doing is basically "abusing" the fact that return can only happen from function or a sourced script and assuming it yields 0 when a return was possible (we're sourced) and 1 if not, while suppressing the error output. You also do that in a subshell. Oddly enough, bash is still OK with placement of the return but does not return from a sourced script and keeps going. So far, so god.


0


1


return



The problem is, that "naked" (w/o explicit value specified) return, just like exit propagate last seen return code (return code of the command immediately preceding it).


return


exit



In other words false; return would be the same thing as return 1. You can also try this out by replacing true and false by (exit 255) and see what happens.


false; return


return 1


true


false


(exit 255)



TL;DR for this construct to work as you expected, change it to return 0.


return 0



I hope I have not missed some corner case, but this should work as an alternative with bash by comparing name of the executed script and a source file. [[ "${BASH_SOURCE}" = ${0} ]] evaluates to 0 if file has not been sourced and 1 if it has. Or replace = with != to get same meaning of values as in the return case above.


[[ "${BASH_SOURCE}" = ${0} ]]


0


1


=


!=


return






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

XNOApgpUpe 7,4zyI3qdxaenokuz 23slqpNMJo8t t3,5fvuR2fgZN3kE523aZLwGABMhXm4Si79KK9OrWilyN62h5RUczITw
GgitG8ekSH,liMTkJ1cx8ZJU0HHc69fjPl,9pQafvESwWv,1nzdCj,fXa,v3wNNwqbB6SL7F,n,z,P9 R9wc6

Popular posts from this blog

Keycloak server returning user_not_found error when user is already imported with LDAP

PHP parse/syntax errors; and how to solve them?

415 Unsupported Media Type while sending json file over REST Template