1

My current setup starts with a function that is ostensibly in .bashrc (.bash_it/custom/funcs.bash to be precise)

#!/usr/bin/env bash
function proset() {
  . proset-core "$@";
}

proset-core does some decrypting of secrets and exports those secrets to the session, hence the need for the . instead of just running it as a script/subshell.

If something goes wrong in proset-core, I use return instead of exit since I don't want the SSH connection to be dropped.

if [ "${APP_JSON}" = "null" ] ; then
  echo -e "\n${redtext}App named $NAME not found in ${APPCONF}. Aborting.${resettext}\n";
  return;
fi

This makes sense in the context of the exported proset function, but precludes usage as a script since return isn't valid except from within a function.

Is there a way to detect how it's being called and return one or the other as appropriate?

3
  • You could investigate SHLVL variable. Commented Mar 8, 2018 at 0:34
  • return || exit -- if one doesn't work, the other will. Commented Mar 9, 2018 at 21:05
  • 1
    BTW, function funcname() { ... } is bad form -- old-ksh format is function funcname {, POSIX-standard format is funcname() {; the idiom that uses both the function prefix and the () is compatible with neither. See wiki.bash-hackers.org/scripting/obsolete -- if you want to pick one or the other practice to learn, the POSIX-y one is probably better; means you aren't in habits that will make your code break when run in /bin/sh, and won't confuse people used to ancient ksh where function makes variables local-by-default (which it doesn't do in bash). Commented Mar 9, 2018 at 21:06

3 Answers 3

2

Just try to return, and exit if it fails.

_retval=$?
return 2>/dev/null || exit "$_retval"

The only case where your code will still be continuing after the return was invoked at top-level (outside of a function) is if you were executed rather than sourced, and should that happen, exiting is the Right Thing.

Sign up to request clarification or add additional context in comments.

1 Comment

BTW you can also declare exit as a function while you source a file to prevent exiting... I use that sometime in shell test scripts to load inline functions then capture the results.
1

Make the builtin variable $SHLVL part of $@ args as the last arg. Then at test point:

if [ "${@: -1}" -lt $SHLVL ]; then
    # SHLVL arg is less than current SHLVL
    # we are in a subshell
    exit
else
    return
fi 

1 Comment

Doesn't this require that any other use of proset-core would need to pass $SHLVL all the time? And when "$@" is empty, also detect the number of args and adjust accordingly. Is there a way to check without changing the arg list to proset-core?
0

Ended up using

calledBy="$(ps -o comm= $PPID)";
if [ "x${calledBy}" = "xsshd" ]; then
  return 1;
else
  exit 1;
fi

since it didn't require passing anything extra. Anything that might cause this to be problematic please comment. Not too worried about being bash-specific or portable.

Credit: get the name of the caller script in bash script

3 Comments

The x$foo is unnecessary here, btw -- [ "$calledBy" = sshd ] is perfectly safe. The only case where that idiom is needed in modern (post-1990) shells is when you're using -a or -o to combine multiple tests in one instance, and POSIX has that syntax marked as obsolescent (search for OB markers in pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html).
...that said, this seems like a lot of overhead for a not-particularly-reliable test (whether you were sourced and whether you're a direct subprocess of sshd are really two different questions!).
...to provide some concrete examples, you might be sourced into a shell that is a child of gnome-terminal or /bin/login rather than sshd, or someone might run ssh hostname 'exec /path/to/your-script', in which case you'll be a direct child of sshd, but executed and not sourced.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.