1

I have a script that I'd like people to source, but optionally so. So they can run it with or without sourcing it, it's up to them.

e.g. The following should both work:

$ . test.sh $ test.sh

The problem is, test.sh contains exit statements if correct args aren't passed in. If someone sources the script, then the exit commands exit the terminal!

I've done a bit of research and see from this StackOverflow post that I could detect if it's being sourced, and do something different, but what would that something different be?

Brad Parks
  • 60,289
  • 61
  • 245
  • 309

2 Answers2

1

There may be better ways to do this, but here's a sample script showing how I got this to work:

bparks@home 
$ set | grep TESTVAR

bparks@home 
$ ./test.sh

  Outputs some useful information to the console. Please pass one arg.

bparks@home 
$ set | grep TESTVAR

bparks@home 
$ . ./test.sh

  Outputs some useful information to the console. Please pass one arg.

bparks@home 
$ set | grep TESTVAR

bparks@home 
$ ./test.sh asdf
export TESTVAR=me

bparks@home 
$ set | grep TESTVAR

bparks@home 
$ . ./test.sh asdf

bparks@home 
$ set | grep TESTVAR
TESTVAR=me

bparks@home 
$

test.sh

#!/usr/bin/env bash

# store if we're sourced or not in a variable
(return 0 2>/dev/null) && SOURCED=1 || SOURCED=0

exitIfNotSourced(){
  [[ "$SOURCED" != "0" ]] || exit;
}

showHelp(){
  IT=$(cat <<EOF

  Outputs some useful information to the console. Please pass one arg.

EOF
  )
  echo "$IT"
}

# Show help if no args supplied - works if sourced or not sourced
if [ -z "$1" ]
then
  showHelp

  exitIfNotSourced;
  return;
fi

# your main script follows 
# this sample shows exporting a variable if sourced, 
# and outputting this to stdout if not sourced

if [ "$SOURCED" == "1" ]
then
  export TESTVAR=me
else
  echo "export TESTVAR=me"
fi
Brad Parks
  • 60,289
  • 61
  • 245
  • 309
1

The normal way to exit from a sourced script is simply to return (optionally adding the desired exit code) outside of any function. Assuming that when run as a command we have the -e flag set, this will also exit from a shell program:

#!/bin/sh -eu

if [ $# = 0 ]
then
    echo "Usage $0 <argument>" >&2 
    return 1
fi

If we're running without -e, we might be able to return || exit instead.

Toby Speight
  • 25,191
  • 47
  • 61
  • 93
  • Thanks for the feedback - yeah I want it to work source and not sourced - can you show an example of this working both ways? – Brad Parks Oct 04 '19 at 15:24
  • I tried it and it works as you give for an example - but I guess the use case for me is I like to have functions that can `exit` at anytime - and this approach doesnt seem to let that happen? – Brad Parks Oct 04 '19 at 16:51