Contents

Shell Cheat Sheets

References

Bourne shell

Bourne shell is sensitive to round brackets (). For example:

1
2
3
4
5
6
7
8
9
# /bin/sh
(echo "1.2.3" | grep -Eq ^[0-9]+\.[0-9]+\.[0-9]+$ && VAL=0) || VAL=1;
echo $VAL; # ''
echo "1.2.3" | grep -Eq ^[0-9]+\.[0-9]+\.[0-9]+$ && VAL=0 || VAL=1;
echo $VAL; # 0

# /bin/bash
(echo "1.2.3" | grep -Eq ^[0-9]+\.[0-9]+\.[0-9]+$ && VAL="OK") || VAL="NOK";
echo $VAL; # OK

Double quotes in Bourne shell make strings un-loopable:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash
# Read a string with spaces using for loop
for value in I like programming;
do
    echo $value;
done

val="I like programming";
for value in $val;
do
    echo $value;
done

# I
# like
# programming

for value in "$val";
do
    echo $value;
done

# I like programming

Attention, IFS can change the default behavior, for example, IFS="" will not split strings by space. The output value will be I like programming.

Shell scripting

Exit when any commands return a non-zero exit code:

1
2
# exit when any command fails
set -e

Further advanced exit strategies are available here

Loop

Loop through directories

1
2
3
4
for d in */ ;
do
    echo "$d"
done

Troubleshooting

Return values in functions

Bash can’t pass around data structures as return values in functions. A return value must be a numeric exit status between 0-255. It’s not recommended to return structured data like below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Don't
get_users() {
    user=(John Dave Amy)
    echo "${user[@]}"
}

give_gifts() {
    local users=$(get_users)

    for user in "${users[@]}"
    do
        echo "Give ${user} a gift"
    done
}

With Bash version 4.3 and above, we can make use of a nameref to pass return data.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Do
get_userz() {
    local -n arr=$1 # use nameref for indirection
    arr=(John Dave Amy)
}

give_gifts() {
    local userz
    get_userz userz

    for user in "${users[@]}"
    do
        echo "Give ${user} a gift"
    done
}

gitlab-ci.yml

YAML files used in GitLab CI does not support colon (:) in commands, i.e. curl -H "access-token: test". Use with care.