SlideShare una empresa de Scribd logo
1 de 32
Descargar para leer sin conexión
Beautiful Bash: A community driven effort
Lets make reading & writing Bash scripts fun again!
Aaron Zauner
azet@azet.org
lambda.co.at:
Highly-Available, Scalable & Secure Distributed Systems
DevOps/Security Meetup Vienna - 17/12/2014
Introduction
Working towards a community style guide
Doing it wrong
Modern Bash scripting (Welcome to 2014!)
Conclusion
Caveat Emptor
I’m not endorsing Bash for large-scale projects, difficult or
performance critical tasks. If your project needs to talk to a
database, object store, interact with a filesystem or dynamically
handle block devices - you SHOULD NOT use Bash in the first
place. You can. But you’ll regret it - I speak from years of
experience doing completely insane stuff in Bash for fun (certainly
not for profit).
Bash is useful for one thing and one thing only: as glue!
..and it’s the glue that holds Linux distributions, Embedded
Appliances and even Commercial networking gear together - so you
better use the best glue on the market, right?
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 1/30
Do we really need another style guide?
For starters: It’s not only a style guide, but more on that later.
A lot of the internet actually runs on poorly written Bash.
Your company probably depends on a lot of Bash-glue.
Everyone uses it on a daily basis to glue userland utilities
together.
Some scripts unintentionally look like they are submissions for
an obfuscated code contest.
There are some style guides (e.g. by Google) and tutorials -
but nothing definitive.
Most books on the subject are ancient and often reflect
personal opinions of authors, outdated Bash versions and
userland utilities and most haven’t been updated in decades.
I don’t know a single good book on Bash. The best resource is
still http://wiki.bash-hackers.org.
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 2/30
Working towards a community style guide
I’ve started collecting style guides, tutorials, write-ups, tools
and debugging projects during the last couple of years.
..chose the best ideas and clearest styles and combined them
into one big community driven effort.
People started contributing.
Nothing is written in stone. Come up with a better idea for a
certain topic and I’ll gladly accept it.
I’ve also included a lot of mistakes people do or even rely on
when writing their (often production) scripts.
I’ve also collected a lot of tricks and shortcuts I’ve learned over
the years specific to bash scripting and the Linux userland.
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 3/30
Bad Example
Here’s a cool and bad example at the same time. rpm2cpio
reimplemented in bash.
As Debian package: Installed-Size: 1044
As Bash script: 4
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 4/30
Bad Example (cont.)
https://trac.macports.org/attachment/ticket/33444/rpm2cpio
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 5/30
Common bad style practices
overusing grep for tasks that Bash can do by itself.
using bourne-shell backticks instead of $() for subshell calls.
.. ever tried to nest backtick subshells? yea. you’ll have to
escape them. instead of e.g.:
$(util1 $(util2 ${some_variable_as_argument})).
manual argument parsing instead of using the getopts builtin.
using awk for arithmetic operations bash can do very well.
.. same goes for expr(1). please stop using it in bash scripts.
.. same goes for bc(1). please stop using it in bash scripts.
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 6/30
Common bad style practices (cont.)
using the echo builtin where printf can (and probably
should) be used.
using seq 1 15 for range expressions instead of {1..15}
many coreutils you do not need & you save on subshell calls.
.. a lot is set as a variable in your environment already
(protip: see what env gives you to work with in the first place)
worst of all: endless and unreadable pipe glue. . . . . . . . . . . .
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 7/30
Common bad style practices (cont.)
So what is more readable to you and probably the angry sysadmin
that might take over your codebase at some point in time?
ls ${long_list_of_parameters} | grep ${foo} | grep -v
grep | pgrep | wc -l | sort | uniq
or
ls ${long_list_of_parameters} 
| grep ${foo} 
| grep -v grep 
| pgrep 
| wc -l 
| sort 
| uniq
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 8/30
awk(1) for everything
But why?
$ du -sh Downloads | awk ‚{ print $1 }‚
366G
$ folder_size=($(du -sh Downloads))
$ echo ${folder_size[1]}
Downloads
$ echo ${folder_size[0]}
366G
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 9/30
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 10/30
Debugging is a mess
One of the reasons nobody should aim for big projects in Bash is
that it is terrible to debug, most of you will know this already.
This project aims to make it easier for you to debug your scripts.
By writing beautiful, solid and testable code.
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 11/30
Modern Bash scripting
Most people don’t know that there are a lot of useful paradigms and
tools that are used for software engineering in serious languages
available also to Bash.
Let’s not kid ourselves: some Bash scripts will run in production,
even for years. They’d better work. And not take your business
offline.
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 12/30
Conventions
I’ve come up with a few conventions:
use #!/usr/bin/env bash
do not use TABs for (consistently use 2, 3 or 4 spaces)
but conditional and loop clauses on the same line:
if ..; then instead of
if ...
then
...
fi
there’re no private functions in Bash, RedHat has a convention
for that, prepend with two underscores function
__my_private_function()
as in Ruby, Python; don’t use indents in switch (case) blocks
always “escape” varabiles. Bad: $MyVar, Good: ${MyVar}.DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 13/30
DocOpt
DocOpt is a Command-line interface description language with
support for all popular programming languages.
http://docopt.org/
https://github.com/docopt
..also for Bash
https://github.com/docopt/docopts
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 14/30
Test Driven Development and Unit tests with Bash
#!/usr/bin/env bats
@test "addition using bc" {
result="$(echo 2+2 | bc)"
[ "$result" -eq 4 ]
}
@test "addition using dc" {
result="$(echo 2 2+p | dc)"
[ "$result" -eq 4 ]
}
. . .
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 15/30
Test Driven Development and Unit tests with Bash (cont.)
1. Sam Stephenson (of rbenv fame) wrote an automated testing
system for Bash scripts called ‘bats’ using TAP (Test Anything
Protocol): https://github.com/sstephenson/bats
2. Sharness: another TAP library. there’s even a Chef cookbook
for it: https://github.com/mlafeldt/sharness
3. Cram: a functional testing framework based on Marcurial’s
unified test format - https://bitheap.org/cram/
4. rnt: Automated testing of commandline interfaces -
https://github.com/roman-neuhauser/rnt
5. shUnit2: is a xUnit framework (similar to PyUnit, JUnit et
cetera) - https://code.google.com/p/shunit2/
6. shpec: Tests/Specs - https://github.com/rylnd/shpec
..there are more, but these I’ve found to be most useful.
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 16/30
Linting
A online Bash style linter:
https://github.com/koalaman/shellcheck
Ubuntu ships with a tool called checkbashisms based on
Debians lintian (portability).
shlint tests for portability between zsh, ksh, bash, dash and
bourne shell (if need be):
https://github.com/duggan/shlint
For Node fans: Grunt task that checks if a Bash script is valid
(not anything else, btw):
https://www.npmjs.com/package/grunt-lint-bash
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 17/30
Inter-shell portability
Personal opinion:
Inter-shell portability doesn’t matter. I’ve spent years writing OS
agnostic bourne-shell scripts. Today every modern OS ships with a
reasonably recent version of Bash. These days Solaris (and FOSS
forks like SmartOS) ship even with a GNU userland. Use Bash.
I love zsh and it can do a lot more. I still use Bash for (semi-)
production scripts. They run basically everywhere when done right.
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 18/30
Defensive Bash programming
As you would in every other language, write helper functions,
test these functions.
Set constants readonly.
Write concise, well defined and tested functions for every
action.
Use the local keyword for function-local variables.
Prepend every function with the function keyword.
Return proper error codes and check for them.
Write unit tests.
Some people write a function main() as people would with
Python. So one can import and test ones main call as well.
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 19/30
Defensive Bash programming (cont.)
function fail() {
local msg=${@}
# handle failure appropriately
cleanup && logger "my message to syslog"
echo "ERROR: ${msg}"
exit 1
}
et cetera
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 20/30
Defensive Bash programming (cont.)
function linux_distro() {
local releasefile=$(cat /etc/*release* 2> /dev/null)
case ${releasefile} in
*Debian*) printf "debiann" ;;
*Suse*) printf "slesn" ;;
*CentOS* | *RedHat*) printf "eln" ;;
*) return 1 ;;
esac
}
...
[[ $(linux_distro) ]] || fail "Unkown distribution!"
readonly linux_distro=$(linux_distro)
...
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 21/30
Defensive Bash programming (cont.)
function debian_version() {
# convert debian version to single unsigned integer
local dv=$(printf "%.f" $(</etc/debian_version))
printf "%u" ${dv}
}
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 22/30
Defensive Bash programming (cont.)
function is_empty() {
local var=${1}
[[ -z ${var} ]]
}
function is_file() {
local file=${1}
[[ -f ${file} ]]
}
function is_dir() {
local dir=${1}
[[ -d ${dir} ]]
}
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 23/30
Signal Handling
Bash supports signal handling with the builtin trap:
# call the fail() function if one
# of these signals is caught by trap:
trap ‚fail "caught signal!"‚ HUP KILL QUIT
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 24/30
Anonymous Functions (Lambdas)
You’ll probably never ever need this in Bash, but it’s possible:
function lambda() {
_f=${1} ; shift
function _l {
eval ${_f};
}
_l ${*} ; unset _l
}
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 25/30
Bash Profiling
Sam Stephenson also wrote a profiler for Bash scripts:
https://github.com/sstephenson/bashprof
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 26/30
Bash Debugging
Hopefully you’ll write code that you do not have to debug often, but
eventually you’ll have to. There’s only one real way to debug a
Bash script unfortunately:
bash -evx script.sh
or setting set -evx in your script directly
that being said, someone wrote a Bash debugger with gdb
command syntax: http://bashdb.sourceforge.net/
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 27/30
Conclusion
There’s a lot more to tell (just ask me afterwards) - but this
was supposed to be a lightning talk.
All this, a lot of references and other projects are mentioned in
my Community Bash Style Guide which is on GitHub.
Please contribute in any way you can if you come up with
useful Bashisms, tricks or find any cool projects.
Any input is very much appreciated!
Fork and open Pull Requests, Issues or Complaints!
https://github.com/azet/community_bash_style_guide
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 28/30
Trivia: Do not try this at home
OOP in Bash:
https://github.com/tomas/skull
https://github.com/kristopolous/TickTick
https://code.google.com/p/object-oriented-bash/
https://github.com/patrickd-/ooengine
http://hipersayanx.blogspot.co.at/2012/12/
object-oriented-programming-in-bash.html
LISP Dialect implemented in Bash:
https://github.com/alandipert/gherkin
The original Macros used in the source of Bourne Shell (To make it
look like ALGOL68 - the author was a big fan):
http://research.swtch.com/shmacro
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 29/30
Thanks for your patience. Are there any questions?
Twitter:
@a_z_e_t
E-Mail:
azet@azet.org
XMPP:
azet@jabber.ccc.de
GitHub:
https://github.com/azet
GPG Fingerprint:
7CB6 197E 385A 02DC 15D8 E223 E4DB 6492 FDB9 B5D5
[I have ECDSA (Brainpool) & EdDSA (Curve25519) subkeys as well.]
DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort
Aaron Zauner 30/30

Más contenido relacionado

La actualidad más candente

Evaluating UCIe based multi-die SoC to meet timing and power
Evaluating UCIe based multi-die SoC to meet timing and power Evaluating UCIe based multi-die SoC to meet timing and power
Evaluating UCIe based multi-die SoC to meet timing and power
Deepak Shankar
 
CETH for XDP [Linux Meetup Santa Clara | July 2016]
CETH for XDP [Linux Meetup Santa Clara | July 2016] CETH for XDP [Linux Meetup Santa Clara | July 2016]
CETH for XDP [Linux Meetup Santa Clara | July 2016]
IO Visor Project
 

La actualidad más candente (20)

Linux BPF Superpowers
Linux BPF SuperpowersLinux BPF Superpowers
Linux BPF Superpowers
 
Introduction to eBPF
Introduction to eBPFIntroduction to eBPF
Introduction to eBPF
 
GS-4106 The AMD GCN Architecture - A Crash Course, by Layla Mah
GS-4106 The AMD GCN Architecture - A Crash Course, by Layla MahGS-4106 The AMD GCN Architecture - A Crash Course, by Layla Mah
GS-4106 The AMD GCN Architecture - A Crash Course, by Layla Mah
 
IBM Tape Update Dezember18 - TS1160
IBM Tape Update Dezember18 - TS1160IBM Tape Update Dezember18 - TS1160
IBM Tape Update Dezember18 - TS1160
 
4章 Linuxカーネル - 割り込み・例外 3
4章 Linuxカーネル - 割り込み・例外 34章 Linuxカーネル - 割り込み・例外 3
4章 Linuxカーネル - 割り込み・例外 3
 
The ideal and reality of NVDIMM RAS
The ideal and reality of NVDIMM RASThe ideal and reality of NVDIMM RAS
The ideal and reality of NVDIMM RAS
 
SFO15-TR9: PSCI, ACPI (and UEFI to boot)
SFO15-TR9: PSCI, ACPI (and UEFI to boot)SFO15-TR9: PSCI, ACPI (and UEFI to boot)
SFO15-TR9: PSCI, ACPI (and UEFI to boot)
 
Evaluating UCIe based multi-die SoC to meet timing and power
Evaluating UCIe based multi-die SoC to meet timing and power Evaluating UCIe based multi-die SoC to meet timing and power
Evaluating UCIe based multi-die SoC to meet timing and power
 
Shared Memory Centric Computing with CXL & OMI
Shared Memory Centric Computing with CXL & OMIShared Memory Centric Computing with CXL & OMI
Shared Memory Centric Computing with CXL & OMI
 
HA, Scalability, DR & MAA in Oracle Database 21c - Overview
HA, Scalability, DR & MAA in Oracle Database 21c - OverviewHA, Scalability, DR & MAA in Oracle Database 21c - Overview
HA, Scalability, DR & MAA in Oracle Database 21c - Overview
 
Ceph on arm64 upload
Ceph on arm64   uploadCeph on arm64   upload
Ceph on arm64 upload
 
Ceph Introduction 2017
Ceph Introduction 2017  Ceph Introduction 2017
Ceph Introduction 2017
 
CETH for XDP [Linux Meetup Santa Clara | July 2016]
CETH for XDP [Linux Meetup Santa Clara | July 2016] CETH for XDP [Linux Meetup Santa Clara | July 2016]
CETH for XDP [Linux Meetup Santa Clara | July 2016]
 
Ceph and RocksDB
Ceph and RocksDBCeph and RocksDB
Ceph and RocksDB
 
Intel dpdk Tutorial
Intel dpdk TutorialIntel dpdk Tutorial
Intel dpdk Tutorial
 
[232] 성능어디까지쥐어짜봤니 송태웅
[232] 성능어디까지쥐어짜봤니 송태웅[232] 성능어디까지쥐어짜봤니 송태웅
[232] 성능어디까지쥐어짜봤니 송태웅
 
Beyond porting
Beyond portingBeyond porting
Beyond porting
 
Bindless Deferred Decals in The Surge 2
Bindless Deferred Decals in The Surge 2Bindless Deferred Decals in The Surge 2
Bindless Deferred Decals in The Surge 2
 
Dpdk pmd
Dpdk pmdDpdk pmd
Dpdk pmd
 
eBPF - Rethinking the Linux Kernel
eBPF - Rethinking the Linux KerneleBPF - Rethinking the Linux Kernel
eBPF - Rethinking the Linux Kernel
 

Similar a Beautiful Bash: Let's make reading and writing bash scripts fun again!

Building an Open Source iOS app: lessons learned
Building an Open Source iOS app: lessons learnedBuilding an Open Source iOS app: lessons learned
Building an Open Source iOS app: lessons learned
Wojciech Koszek
 
Lpi Part 1 Linux Fundamentals
Lpi Part 1 Linux FundamentalsLpi Part 1 Linux Fundamentals
Lpi Part 1 Linux Fundamentals
YemenLinux
 
Bash shell programming in linux
Bash shell programming in linuxBash shell programming in linux
Bash shell programming in linux
Norberto Angulo
 
Linux: Beyond ls and cd
Linux: Beyond ls and cdLinux: Beyond ls and cd
Linux: Beyond ls and cd
jacko91
 
4Developers 2015: Continuous Security in DevOps - Maciej Lasyk
4Developers 2015: Continuous Security in DevOps - Maciej Lasyk4Developers 2015: Continuous Security in DevOps - Maciej Lasyk
4Developers 2015: Continuous Security in DevOps - Maciej Lasyk
PROIDEA
 

Similar a Beautiful Bash: Let's make reading and writing bash scripts fun again! (20)

Bash is not a second zone citizen programming language
Bash is not a second zone citizen programming languageBash is not a second zone citizen programming language
Bash is not a second zone citizen programming language
 
Building an Open Source iOS app: lessons learned
Building an Open Source iOS app: lessons learnedBuilding an Open Source iOS app: lessons learned
Building an Open Source iOS app: lessons learned
 
How to build LibreOffice on your desktop
How to build LibreOffice on your desktopHow to build LibreOffice on your desktop
How to build LibreOffice on your desktop
 
Porting your favourite cmdline tool to Android
Porting your favourite cmdline tool to AndroidPorting your favourite cmdline tool to Android
Porting your favourite cmdline tool to Android
 
Automate Yo' Self
Automate Yo' SelfAutomate Yo' Self
Automate Yo' Self
 
The Cost Of Free Linux
The Cost Of Free LinuxThe Cost Of Free Linux
The Cost Of Free Linux
 
Lpi Part 1 Linux Fundamentals
Lpi Part 1 Linux FundamentalsLpi Part 1 Linux Fundamentals
Lpi Part 1 Linux Fundamentals
 
Reverse Engineering in Linux - The tools showcase
Reverse Engineering in Linux - The tools showcaseReverse Engineering in Linux - The tools showcase
Reverse Engineering in Linux - The tools showcase
 
Bash shell programming in linux
Bash shell programming in linuxBash shell programming in linux
Bash shell programming in linux
 
3stages Wdn08 V3
3stages Wdn08 V33stages Wdn08 V3
3stages Wdn08 V3
 
Linux: Beyond ls and cd
Linux: Beyond ls and cdLinux: Beyond ls and cd
Linux: Beyond ls and cd
 
Foss Presentation
Foss PresentationFoss Presentation
Foss Presentation
 
Jenkins pipeline -- Gentle Introduction
Jenkins pipeline -- Gentle IntroductionJenkins pipeline -- Gentle Introduction
Jenkins pipeline -- Gentle Introduction
 
Resources For Floss Projects
Resources For Floss ProjectsResources For Floss Projects
Resources For Floss Projects
 
Open event (show&tell april 2016)
Open event (show&tell april 2016)Open event (show&tell april 2016)
Open event (show&tell april 2016)
 
hw1a
hw1ahw1a
hw1a
 
hw1a
hw1ahw1a
hw1a
 
Pyhton-1a-Basics.pdf
Pyhton-1a-Basics.pdfPyhton-1a-Basics.pdf
Pyhton-1a-Basics.pdf
 
4Developers 2015: Continuous Security in DevOps - Maciej Lasyk
4Developers 2015: Continuous Security in DevOps - Maciej Lasyk4Developers 2015: Continuous Security in DevOps - Maciej Lasyk
4Developers 2015: Continuous Security in DevOps - Maciej Lasyk
 
Continuous Security in DevOps
Continuous Security in DevOpsContinuous Security in DevOps
Continuous Security in DevOps
 

Más de Aaron Zauner

State of Transport Security in the E-Mail Ecosystem at Large
State of Transport Security in the E-Mail Ecosystem at LargeState of Transport Security in the E-Mail Ecosystem at Large
State of Transport Security in the E-Mail Ecosystem at Large
Aaron Zauner
 
Introduction to and survey of TLS security (BsidesHH 2014)
Introduction to and survey of TLS security (BsidesHH 2014)Introduction to and survey of TLS security (BsidesHH 2014)
Introduction to and survey of TLS security (BsidesHH 2014)
Aaron Zauner
 
Introduction to and survey of TLS Security
Introduction to and survey of TLS SecurityIntroduction to and survey of TLS Security
Introduction to and survey of TLS Security
Aaron Zauner
 
How to save the environment
How to save the environmentHow to save the environment
How to save the environment
Aaron Zauner
 

Más de Aaron Zauner (13)

Because "use urandom" isn't everything: a deep dive into CSPRNGs in Operating...
Because "use urandom" isn't everything: a deep dive into CSPRNGs in Operating...Because "use urandom" isn't everything: a deep dive into CSPRNGs in Operating...
Because "use urandom" isn't everything: a deep dive into CSPRNGs in Operating...
 
[BlackHat USA 2016] Nonce-Disrespecting Adversaries: Practical Forgery Attack...
[BlackHat USA 2016] Nonce-Disrespecting Adversaries: Practical Forgery Attack...[BlackHat USA 2016] Nonce-Disrespecting Adversaries: Practical Forgery Attack...
[BlackHat USA 2016] Nonce-Disrespecting Adversaries: Practical Forgery Attack...
 
No need for Black Chambers: Testing TLS in the E-Mail Ecosystem at Large (hac...
No need for Black Chambers: Testing TLS in the E-Mail Ecosystem at Large (hac...No need for Black Chambers: Testing TLS in the E-Mail Ecosystem at Large (hac...
No need for Black Chambers: Testing TLS in the E-Mail Ecosystem at Large (hac...
 
State of Transport Security in the E-Mail Ecosystem at Large
State of Transport Security in the E-Mail Ecosystem at LargeState of Transport Security in the E-Mail Ecosystem at Large
State of Transport Security in the E-Mail Ecosystem at Large
 
Javascript Object Signing & Encryption
Javascript Object Signing & EncryptionJavascript Object Signing & Encryption
Javascript Object Signing & Encryption
 
Introduction to and survey of TLS security (BsidesHH 2014)
Introduction to and survey of TLS security (BsidesHH 2014)Introduction to and survey of TLS security (BsidesHH 2014)
Introduction to and survey of TLS security (BsidesHH 2014)
 
Introduction to and survey of TLS Security
Introduction to and survey of TLS SecurityIntroduction to and survey of TLS Security
Introduction to and survey of TLS Security
 
[IETF Part] BetterCrypto Workshop @ Hack.lu 2014
[IETF Part] BetterCrypto Workshop @ Hack.lu 2014[IETF Part] BetterCrypto Workshop @ Hack.lu 2014
[IETF Part] BetterCrypto Workshop @ Hack.lu 2014
 
[Attacks Part] BetterCrypto Workshop @ Hack.lu 2014
[Attacks Part] BetterCrypto Workshop @ Hack.lu 2014 [Attacks Part] BetterCrypto Workshop @ Hack.lu 2014
[Attacks Part] BetterCrypto Workshop @ Hack.lu 2014
 
Introduction to and survey of TLS Security
Introduction to and survey of TLS SecurityIntroduction to and survey of TLS Security
Introduction to and survey of TLS Security
 
BetterCrypto: Applied Crypto Hardening
BetterCrypto: Applied Crypto HardeningBetterCrypto: Applied Crypto Hardening
BetterCrypto: Applied Crypto Hardening
 
How to save the environment
How to save the environmentHow to save the environment
How to save the environment
 
Sc12 workshop-writeup
Sc12 workshop-writeupSc12 workshop-writeup
Sc12 workshop-writeup
 

Último

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Último (20)

Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 

Beautiful Bash: Let's make reading and writing bash scripts fun again!

  • 1. Beautiful Bash: A community driven effort Lets make reading & writing Bash scripts fun again! Aaron Zauner azet@azet.org lambda.co.at: Highly-Available, Scalable & Secure Distributed Systems DevOps/Security Meetup Vienna - 17/12/2014
  • 2. Introduction Working towards a community style guide Doing it wrong Modern Bash scripting (Welcome to 2014!) Conclusion
  • 3. Caveat Emptor I’m not endorsing Bash for large-scale projects, difficult or performance critical tasks. If your project needs to talk to a database, object store, interact with a filesystem or dynamically handle block devices - you SHOULD NOT use Bash in the first place. You can. But you’ll regret it - I speak from years of experience doing completely insane stuff in Bash for fun (certainly not for profit). Bash is useful for one thing and one thing only: as glue! ..and it’s the glue that holds Linux distributions, Embedded Appliances and even Commercial networking gear together - so you better use the best glue on the market, right? DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 1/30
  • 4. Do we really need another style guide? For starters: It’s not only a style guide, but more on that later. A lot of the internet actually runs on poorly written Bash. Your company probably depends on a lot of Bash-glue. Everyone uses it on a daily basis to glue userland utilities together. Some scripts unintentionally look like they are submissions for an obfuscated code contest. There are some style guides (e.g. by Google) and tutorials - but nothing definitive. Most books on the subject are ancient and often reflect personal opinions of authors, outdated Bash versions and userland utilities and most haven’t been updated in decades. I don’t know a single good book on Bash. The best resource is still http://wiki.bash-hackers.org. DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 2/30
  • 5. Working towards a community style guide I’ve started collecting style guides, tutorials, write-ups, tools and debugging projects during the last couple of years. ..chose the best ideas and clearest styles and combined them into one big community driven effort. People started contributing. Nothing is written in stone. Come up with a better idea for a certain topic and I’ll gladly accept it. I’ve also included a lot of mistakes people do or even rely on when writing their (often production) scripts. I’ve also collected a lot of tricks and shortcuts I’ve learned over the years specific to bash scripting and the Linux userland. DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 3/30
  • 6. Bad Example Here’s a cool and bad example at the same time. rpm2cpio reimplemented in bash. As Debian package: Installed-Size: 1044 As Bash script: 4 DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 4/30
  • 7. Bad Example (cont.) https://trac.macports.org/attachment/ticket/33444/rpm2cpio DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 5/30
  • 8. Common bad style practices overusing grep for tasks that Bash can do by itself. using bourne-shell backticks instead of $() for subshell calls. .. ever tried to nest backtick subshells? yea. you’ll have to escape them. instead of e.g.: $(util1 $(util2 ${some_variable_as_argument})). manual argument parsing instead of using the getopts builtin. using awk for arithmetic operations bash can do very well. .. same goes for expr(1). please stop using it in bash scripts. .. same goes for bc(1). please stop using it in bash scripts. DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 6/30
  • 9. Common bad style practices (cont.) using the echo builtin where printf can (and probably should) be used. using seq 1 15 for range expressions instead of {1..15} many coreutils you do not need & you save on subshell calls. .. a lot is set as a variable in your environment already (protip: see what env gives you to work with in the first place) worst of all: endless and unreadable pipe glue. . . . . . . . . . . . DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 7/30
  • 10. Common bad style practices (cont.) So what is more readable to you and probably the angry sysadmin that might take over your codebase at some point in time? ls ${long_list_of_parameters} | grep ${foo} | grep -v grep | pgrep | wc -l | sort | uniq or ls ${long_list_of_parameters} | grep ${foo} | grep -v grep | pgrep | wc -l | sort | uniq DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 8/30
  • 11. awk(1) for everything But why? $ du -sh Downloads | awk ‚{ print $1 }‚ 366G $ folder_size=($(du -sh Downloads)) $ echo ${folder_size[1]} Downloads $ echo ${folder_size[0]} 366G DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 9/30
  • 12. DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 10/30
  • 13. Debugging is a mess One of the reasons nobody should aim for big projects in Bash is that it is terrible to debug, most of you will know this already. This project aims to make it easier for you to debug your scripts. By writing beautiful, solid and testable code. DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 11/30
  • 14. Modern Bash scripting Most people don’t know that there are a lot of useful paradigms and tools that are used for software engineering in serious languages available also to Bash. Let’s not kid ourselves: some Bash scripts will run in production, even for years. They’d better work. And not take your business offline. DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 12/30
  • 15. Conventions I’ve come up with a few conventions: use #!/usr/bin/env bash do not use TABs for (consistently use 2, 3 or 4 spaces) but conditional and loop clauses on the same line: if ..; then instead of if ... then ... fi there’re no private functions in Bash, RedHat has a convention for that, prepend with two underscores function __my_private_function() as in Ruby, Python; don’t use indents in switch (case) blocks always “escape” varabiles. Bad: $MyVar, Good: ${MyVar}.DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 13/30
  • 16. DocOpt DocOpt is a Command-line interface description language with support for all popular programming languages. http://docopt.org/ https://github.com/docopt ..also for Bash https://github.com/docopt/docopts DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 14/30
  • 17. Test Driven Development and Unit tests with Bash #!/usr/bin/env bats @test "addition using bc" { result="$(echo 2+2 | bc)" [ "$result" -eq 4 ] } @test "addition using dc" { result="$(echo 2 2+p | dc)" [ "$result" -eq 4 ] } . . . DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 15/30
  • 18. Test Driven Development and Unit tests with Bash (cont.) 1. Sam Stephenson (of rbenv fame) wrote an automated testing system for Bash scripts called ‘bats’ using TAP (Test Anything Protocol): https://github.com/sstephenson/bats 2. Sharness: another TAP library. there’s even a Chef cookbook for it: https://github.com/mlafeldt/sharness 3. Cram: a functional testing framework based on Marcurial’s unified test format - https://bitheap.org/cram/ 4. rnt: Automated testing of commandline interfaces - https://github.com/roman-neuhauser/rnt 5. shUnit2: is a xUnit framework (similar to PyUnit, JUnit et cetera) - https://code.google.com/p/shunit2/ 6. shpec: Tests/Specs - https://github.com/rylnd/shpec ..there are more, but these I’ve found to be most useful. DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 16/30
  • 19. Linting A online Bash style linter: https://github.com/koalaman/shellcheck Ubuntu ships with a tool called checkbashisms based on Debians lintian (portability). shlint tests for portability between zsh, ksh, bash, dash and bourne shell (if need be): https://github.com/duggan/shlint For Node fans: Grunt task that checks if a Bash script is valid (not anything else, btw): https://www.npmjs.com/package/grunt-lint-bash DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 17/30
  • 20. Inter-shell portability Personal opinion: Inter-shell portability doesn’t matter. I’ve spent years writing OS agnostic bourne-shell scripts. Today every modern OS ships with a reasonably recent version of Bash. These days Solaris (and FOSS forks like SmartOS) ship even with a GNU userland. Use Bash. I love zsh and it can do a lot more. I still use Bash for (semi-) production scripts. They run basically everywhere when done right. DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 18/30
  • 21. Defensive Bash programming As you would in every other language, write helper functions, test these functions. Set constants readonly. Write concise, well defined and tested functions for every action. Use the local keyword for function-local variables. Prepend every function with the function keyword. Return proper error codes and check for them. Write unit tests. Some people write a function main() as people would with Python. So one can import and test ones main call as well. DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 19/30
  • 22. Defensive Bash programming (cont.) function fail() { local msg=${@} # handle failure appropriately cleanup && logger "my message to syslog" echo "ERROR: ${msg}" exit 1 } et cetera DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 20/30
  • 23. Defensive Bash programming (cont.) function linux_distro() { local releasefile=$(cat /etc/*release* 2> /dev/null) case ${releasefile} in *Debian*) printf "debiann" ;; *Suse*) printf "slesn" ;; *CentOS* | *RedHat*) printf "eln" ;; *) return 1 ;; esac } ... [[ $(linux_distro) ]] || fail "Unkown distribution!" readonly linux_distro=$(linux_distro) ... DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 21/30
  • 24. Defensive Bash programming (cont.) function debian_version() { # convert debian version to single unsigned integer local dv=$(printf "%.f" $(</etc/debian_version)) printf "%u" ${dv} } DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 22/30
  • 25. Defensive Bash programming (cont.) function is_empty() { local var=${1} [[ -z ${var} ]] } function is_file() { local file=${1} [[ -f ${file} ]] } function is_dir() { local dir=${1} [[ -d ${dir} ]] } DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 23/30
  • 26. Signal Handling Bash supports signal handling with the builtin trap: # call the fail() function if one # of these signals is caught by trap: trap ‚fail "caught signal!"‚ HUP KILL QUIT DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 24/30
  • 27. Anonymous Functions (Lambdas) You’ll probably never ever need this in Bash, but it’s possible: function lambda() { _f=${1} ; shift function _l { eval ${_f}; } _l ${*} ; unset _l } DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 25/30
  • 28. Bash Profiling Sam Stephenson also wrote a profiler for Bash scripts: https://github.com/sstephenson/bashprof DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 26/30
  • 29. Bash Debugging Hopefully you’ll write code that you do not have to debug often, but eventually you’ll have to. There’s only one real way to debug a Bash script unfortunately: bash -evx script.sh or setting set -evx in your script directly that being said, someone wrote a Bash debugger with gdb command syntax: http://bashdb.sourceforge.net/ DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 27/30
  • 30. Conclusion There’s a lot more to tell (just ask me afterwards) - but this was supposed to be a lightning talk. All this, a lot of references and other projects are mentioned in my Community Bash Style Guide which is on GitHub. Please contribute in any way you can if you come up with useful Bashisms, tricks or find any cool projects. Any input is very much appreciated! Fork and open Pull Requests, Issues or Complaints! https://github.com/azet/community_bash_style_guide DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 28/30
  • 31. Trivia: Do not try this at home OOP in Bash: https://github.com/tomas/skull https://github.com/kristopolous/TickTick https://code.google.com/p/object-oriented-bash/ https://github.com/patrickd-/ooengine http://hipersayanx.blogspot.co.at/2012/12/ object-oriented-programming-in-bash.html LISP Dialect implemented in Bash: https://github.com/alandipert/gherkin The original Macros used in the source of Bourne Shell (To make it look like ALGOL68 - the author was a big fan): http://research.swtch.com/shmacro DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 29/30
  • 32. Thanks for your patience. Are there any questions? Twitter: @a_z_e_t E-Mail: azet@azet.org XMPP: azet@jabber.ccc.de GitHub: https://github.com/azet GPG Fingerprint: 7CB6 197E 385A 02DC 15D8 E223 E4DB 6492 FDB9 B5D5 [I have ECDSA (Brainpool) & EdDSA (Curve25519) subkeys as well.] DevOps/Security Meetup Vienna - 17/12/2014 Beautiful Bash: A community driven effort Aaron Zauner 30/30