Mahmoud Zalt
Mahmoud Zalt

Reputation: 31130

How to syntax check a shell script before sourcing it?

I want to run this command source .env (sourcing a .env file) and if the .env file had some errors while sourcing. I want to show a message before the error output "Hey you got errors in your .env" else if there's no error, I don't want to show anything.

Here's a code sample that needs editing:

#!/bin/zsh

env_auto_sourcing() {
  if [[ -f .env ]]; then    

    OUTPUT="$(source .env &> /dev/null)" 
    echo "${OUTPUT}"

    if [ -n "$OUTPUT" ]; then
        echo "Hey you got errors in your .env"
        echo "$OUTPUT"

  fi
}

Upvotes: 2

Views: 3070

Answers (2)

MaXi32
MaXi32

Reputation: 668

Why not just use the exit code from the command source ?

You don't have to use bash -n for this because ...

If let's say your .env file contains these 2 invalid lines:

dsadsd
sdss

If you run your current accepted code using the example above:

if errs=$(bash -n .env 2>&1);

the above condition will fail to stop the file from sourcing.

So, you can use source command return code to handle all of this:

#!/bin/bash
# This doesn't actually source it. It just test if source is working
errs=$(source ".env" 2>&1 >/dev/null)
# get the return code
retval=$?
#echo "${retval}"
if [ ${retval} = 0 ]; then
  # Do another check for any syntax error
  if [ -n "${errs}" ]; then
    echo "The source file returns 0 but you got syntax errors: "
    echo "Error details:"
    printf "%s\n" "${errs}"
    exit 1
  else
    # Success here. we know that this command works without error so we source it
    echo "The source file returns 0 and no syntax errors: "
    source ".env"
  fi
else
  echo "The source command returns an error code ${retval}: "
  echo "Error details:"
  printf "%s\n" "${errs}"
  exit 1
fi

The best thing with this approach is, it will check both bash syntax and source syntax as well:

Now you can test this data in your env file:

-
~
@
~<
>

Upvotes: 1

codeforester
codeforester

Reputation: 42999

You could use bash -n (zsh has has a -n option as well) to syntax check your script before sourcing it:

 env_auto_sourcing() {
  if [[ -f .env ]]; then
    if errs=$(bash -n .env 2>&1); 
        then source .env; 
    else 
        printf '%s\n' "Hey you got errors" "$errs"; 
    fi
  fi
 }

Storing the syntax check errors in a file is a little cleaner than the subshell approach you have used in your code.

bash -n has a few pitfalls as seen here:

Upvotes: 4

Related Questions