Skip to content

Instantly share code, notes, and snippets.

@Kjaer
Created July 31, 2022 15:30
Show Gist options
  • Save Kjaer/f12ddf881dc71e7a932d4f76a7ce8109 to your computer and use it in GitHub Desktop.
Save Kjaer/f12ddf881dc71e7a932d4f76a7ce8109 to your computer and use it in GitHub Desktop.
Bash script knowledge with environment variables.
if [[ "${CYPRESS_ACCOUNT_ID:-}" ]]
then
export GRAPHQL_ACCOUNT_ID=$CYPRESS_ACCOUNT_ID && echo $GRAPHQL_ACCOUNT_ID
else
export GRAPHQL_ACCOUNT_ID=$(grep GRAPHQL_ACCOUNT_ID .env.local | cut -d '=' -f2) && echo $GRAPHQL_ACCOUNT_ID
fi
if [[ "${CYPRESS_API_TOKEN:-}" ]]
then
export GRAPHQL_AUTHORIZATION=$CYPRESS_API_TOKEN && echo $GRAPHQL_AUTHORIZATION
else
export GRAPHQL_AUTHORIZATION=$(grep GRAPHQL_AUTHORIZATION .env.local | cut -d '=' -f2) && echo $GRAPHQL_AUTHORIZATION
fi
@Kjaer
Copy link
Author

Kjaer commented Aug 19, 2022

I am gonna rip this shell script apart and explain how each piece works:

  1. test -z

CYPRESS_ACCOUNT_ID is an environment variable. I am expecting CYPRESS_ACCOUNT_ID variable to be available in the shell process' scope. In order to do that, I am using test command. test command is

condition evaluation utility

(from man page). You can consider it, as if keyword in any programming language. It evaluates the given expression and return true/false result.


In fact, it does not return true/false, it just for simplifying the explanation. According to man page again,

if it evaluates to true, returns a zero (true) exit status; otherwise it returns 1 (false).


-z parameter is string length checking argument for test command

-z string True if the length of string is zero.

so this leads us to second part,

  1. "${CYPRESS_ACCOUNT_ID:-}\"

Pay attention to " (quotation) character because test -z requires a string in order to evaluate. Let's keep that detail in our mind and continue, ${}. It is called parameter expansion.

Parameter expansion is the procedure to get the value from the referenced entity,

(https://wiki.bash-hackers.org/syntax/pe). entity is mentioned above for which the variable itself in our case.
It's very similar thing that interpolation of template literals in EcmaScript. But please do not get confused, it is not the same thing.

:- means use given default value, if I may explain over an example:

$ NAME=${NON_EXIST_VARIABLE:-JOHN DOE}
$ echo $NAME
JOHN DOE

As the example illustrates, in the given parameter expansion block (${}) given variable is not defined, null or empty, it uses the given default value. It's a similar concept to function's default parameters.

So I hope this piece "${CYPRESS_ACCOUNT_ID:-}" started to make sense. It's expand the CYPRESS_ACCOUNT_ID variable and returns the value in it, if there's no value :- kicks in and returns nothing. Because if CYPRESS_ACCOUNT_ID is not defined, I want nothing as default value, so the final result would be "" empty string because I wrapped the entire expression with " quotations marks purposefully.

You may ask yourself, why don't we use the ${CYPRESS_ACCOUNT_ID} directly with the test command instead of all the fuss I just explain. Suit yourself:

Screenshot 2022-07-30 at 23 00 34

I am in deep appreciation to yarn shell, not throwing error when it's running "${CYPRESS_ACCOUNT_ID:-}". Because, if I ran the previous command (without :-) in shell, It's like:

Screenshot 2022-07-30 at 23 03 53

CONSISTENT!
(life of a frontend is never easy :(( )

  1. &&

This is the easiest part. I can describe it like, it lets you run next command if the previous commands run successfully.

Screenshot 2022-07-30 at 23 24 23

Otherwise, it stops and won't continue to the next command.

  1. ACCOUNT_ID=$(grep GRAPHQL_ACCOUNT_ID .env.local | cut -d '=' -f2)

ACCOUNT_ID is the interim variable that I am using. $() is again another bash specific operation called Command Substitution (https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html) it basically substitutes given command with its result:

Screenshot 2022-07-31 at 00 00 07

If you don't substitute command result but assign directly, you're not able to assign the variable.

Let me continue with grep command. grep is a pattern searcher. It returns the result that match with given pattern on specified source (from man page). Here, GRAPHQL_ACCOUNT_ID is the given pattern and .env.local is the source. cut is like sub string command:

The cut utility cuts out selected portions of each line from given sources
(from man page)

-d parameter of cut is letting you able to specify delimiter. Here is the equal sign = is delimiter.
-f means field. It lets you pick which field after cut-out.
(from man page)

Screenshot 2022-07-30 at 23 45 28

  1. ||

Double pipe is the opposite of double ampersand (&&). It allows running command, if the previous command failed.

Screenshot 2022-07-31 at 00 05 37

BONUS:
Screenshot 2022-07-30 at 23 24 23

  1. ACCOUNT_ID=$CYPRESS_ACCOUNT_ID

It's a variable assigning. Simply, it assigns ACCOUNT_ID to CYPRESS_ACCOUNT_ID's value (mind the $ sign). Because CYPRESS_ACCOUNT_ID is defined and present in the terminal process scope.

  1. echo $ACCOUNT_ID

This is actually simple but important part. Because So far we chained 4 command and condition. When this condition is met, some value will be assigned to ACCOUNT_ID and by echoing its value, I can use it later with command substitution: $(yarn codegen:auth.account.id)

Bottom line of this entire shell script is mimicing ternary operator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment