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.