Slide 1

Slide 1 text

.co.il www. SHELL _scripting_

Slide 2

Slide 2 text

.co.il www. Evgeny Zislis www.devops.co.il il.linkedin.com/in/evgenyzislis

Slide 3

Slide 3 text

.co.il www. unix process basics

Slide 4

Slide 4 text

.co.il www. parse invocation arguments while read a line from stdin process read line print errors to stderr print output to stdout end exit with return code standard input standard output standard error rc exec + arguments

Slide 5

Slide 5 text

.co.il www. cmd arg1 arg2 cmd > file cmd >> file cmd 2> file cmd < file cmd ; echo $?

Slide 6

Slide 6 text

.co.il www. conditions

Slide 7

Slide 7 text

.co.il www. if [ "foobar" = "foobar" ] then echo "They are equal" else echo "They are not equal" fi

Slide 8

Slide 8 text

.co.il www. [ "foobar" = "foobar" ] && \ echo "They are equal"

Slide 9

Slide 9 text

.co.il www. [ "foobar" = "foobar" ] || \ echo "They are not equal" [ "foobar" != "foobar" ] && \ echo "They are not equal"

Slide 10

Slide 10 text

.co.il www. [ "foobar" = "foobar" ] && { echo "They are equal" } || { echo "They are not equal" }

Slide 11

Slide 11 text

.co.il www. cmd || exec_when_fail cmd && exec_when_success

Slide 12

Slide 12 text

.co.il www. cmd > file cmd >> file

Slide 13

Slide 13 text

.co.il www. | 2 -2 -4 | A = | -1 3 4 | | 1 -2 -3 |

Slide 14

Slide 14 text

.co.il www. | 2 -2 -4 | A = | -1 3 4 | | 1 -2 -3 | A2 = ?

Slide 15

Slide 15 text

.co.il www. | 2 -2 -4 | A = | -1 3 4 | | 1 -2 -3 | A2 = A A321 = ?

Slide 16

Slide 16 text

.co.il www. | 2 -2 -4 | An = | -1 3 4 | | 1 -2 -3 |

Slide 17

Slide 17 text

.co.il www. idempotence

Slide 18

Slide 18 text

.co.il www. #!/bin/bash d="/home/evgeny/.ssh" [ -d "$d" ] || { mkdir "$d" chown evgeny "$d" chmod u+rwx,go-rwx "$d" }

Slide 19

Slide 19 text

.co.il www. bash strict mode

Slide 20

Slide 20 text

.co.il www. #!/bin/bash set -o errexit # set -e set -o nounset # set -u set -o pipefail IFS="\n\t"

Slide 21

Slide 21 text

.co.il www. shellcheck.net

Slide 22

Slide 22 text

.co.il www. shell unit testing

Slide 23

Slide 23 text

.co.il www. #!/usr/bin/env bats @test "git binary is found in PATH" { run "which git" [ "$status" -eq 0 ] } github.com/sstephenson/bats/

Slide 24

Slide 24 text

.co.il www. example unit testing

Slide 25

Slide 25 text

.co.il www. git_rev_email() { git rev-list -1 --pretty='format:%ae' "$@" | tail -1 } git_rev_name() { git rev-list -1 --pretty='format:%an' "$@" | tail -1 }

Slide 26

Slide 26 text

.co.il www. email_fmt='^[A-Za-z0-9]\+@..\.example\.com$' validate_email() { local rev=$1; shift local name; name=$(git_rev_name "$rev") local email; email=$(git_rev_email "$rev") local ldapname; ldapname=$(ldap_name_from_email "$email") echo "$email" | grep "$email_fmt" >/dev/null || { echo "ERROR: non-company e-mail in commit:" \ "$email in $(git_short_sha1 "$rev")" return 1 } [ "$name" != "$ldapname" ] && { echo "WARNING: name '$name' in commit $(git_short_sha1 "$rev")" \ "differs from '$ldapname' associated with $email" } return 0 }

Slide 27

Slide 27 text

.co.il www. rev1="a82e0790910f2589373ff34a8416f72f8b25857d" invalid_name="Foo Bar" invalid_email="[email protected]" mock_invalid_name() { assertEquals "$rev1" "$1"; echo "$invalid_name"; } mock_invalid_email() { assertEquals "$rev1" "$1"; echo "$invalid_email"; } testBadEmail() { git_rev_name() { mock_invalid_name "$@"; } git_rev_email() { mock_invalid_email "$@"; } ldap_name_from_email() { mock_ldap_valid_name "$@"; } stdout=$( validate_email "$rev1" ) rc=$? assertEquals "invalid email prints an error" \ "ERROR: non-company e-mail in commit: ${invalid_email} in $(git_short_sha1 "$rev1")" \ "$stdout" assertEquals "return code is error" 1 "$rc" } . "$(dirname "$0")/../shunit2"

Slide 28

Slide 28 text

.co.il www. We invite you to join Operations Israel Facebook group on on.fb.me/Ops-IL link to slides dvps.me/ops-shell-scripting Thank you! www.devops.co.il