Monday, 24 September 2018

bash best practices

Bash best practices

A few hints on bash best practice:

* use #!/usr/bin/env bash .. this is more portable but you cant rely on a specific version
* use set, dont use options to bash - if someone runs your script with bash scriptname then it will ignore the options to bash
* use {} to enclose variables - can cause mistakes if you donr - e.g. variable name becomes VAR_ext rather than what you wanted
* to ensure you always have a value, set defaults - e.g. "${MYNAME}" = "Stuart" - MYNAME defaults to Stuart if not already set
* use spaces for tabs, not tabs - tab not portable
* max line length of 80 characters for readability - use \ to split of lines if needed
* dont have whitespace at end of lines as may confuse source code control like git
* use $(command) instead of backticks
* variables and function names lowercase and underscores - use meaninful names
* constants should be in caps, declare them first in file
* use readonly to set a variable readonly
* can use local to make a variable specific to a function
* put functions together below the constants, I order the functions alphabetically as easier to find
* use a main function if using multiple functions
* check return values from functions
* avoid eval - munges input
* [[ .. ]] is better than test or /usr/bin/[ - stops pathname expansion and word splitting
* comment difficult bits of code
* insecure to have suid/sgid
* i prefer to have .sh extension so easy to recognise file
### good set options:

* -e exit script immediately if command fails
* -o pipefail fails if any part of a pipe fails
* -u treat unset variables as an error and exit immediately
* suggest second line of bash script is: set -eou pipefail
* -x prints each command before executing it - expands arguments also
* use -E if script contains traps
* to start with using a program like shellcheck can be useful - gives your scripts a quick checkover
* a useful tool if you use vim is the bash support plugin - see


Currently working on creating a large repo - copied a lot of the packages to a VM in my home test lab - on extracting 15Gb of packages I noticed I was running short on space (had about 20Gb free but wanted to ensure extract didnt fail).

running the old du -hs * from / I noticed /var had a lot of storage being used.
(yes I dont have separate partitions on my smaller VMs)

Looking further I could see that it was pretty much being used in /var/log/journal:

# journalctl --disk-usage
Archived and active journals take up 3.9G in the file system.

I'm really not that interested in these logs - and so will add the following modification to my ansible scripts:

modify /etc/systemd/journald.conf => SystemMaxUse=100M

I then run:

systemctl kill --kill-who=main --signal=SIGUSR2 systemd-journald.service


systemctl restart systemd-journald.service

running check again:

# journalctl --disk-usage
Archived and active journals take up 80.0M in the file system.

cool - lots of space cleared on my VM!

(I do recommend on servers having separate filesystems, and bigger ones than I use - however on home system I have 2Tb worth of ssd - this has to be shared amongst numerous smaller VMs)

Tuesday, 11 September 2018


What is TCP/IP

tcp/ip is basically a set of rules/standards - see darpa standard
transmission control protocol/internet protocol
based on OSI model - but slightly different - 4 layers instead of 7

Image result for 4 layers of tcp/ip

tcp is essentially the transport layer  - responsible for splitting up the data and posting it on the physical link  - but like a clerk in an office getting lots of things ready to deliver to a customer - splitting it into manageable parcels - ip is like the postman - he picks up the parcels and routes them to their destination.

A TCP packet runs ontop of an IP packet.

TCP Packet:

enter image description here

IP packet:

Image result for ip packet

Three way handshake:

1. A tcp connection is established via a three way handshake - client sends a SYN (synchronize) packet to server with a random sequence number.

2. server sends back a SYN-ACK - containing another random sequence number and an ACK number to acknowledge clients sequence number

3. client then sends an ACK number to server, which aknowledges the servers sequence number.

now that the sequence numbers are synchronized, both ends can now send and receive data independently
Image result for three way handshake

Saturday, 21 April 2018

connect ubuntu to wifi from command line

so i have a server install of a beta release of bionic beaver - ubuntu 18.04 - I want to connect this to wifi as I'm not near my cobbler server and cant connect to it via ethernet at the moment.

If we've connected before we can view previous connections:

nmcli c

- havent had any previous connections so no luck there.

to see wifi hotspots near me:

root@bionic-beaver-x8664:~# nmcli d wifi list
IN-USE  SSID                  MODE   CHAN  RATE        SIGNAL  BARS              SECURITY
abramshumps                       Infra  13    270 Mbit/s              100     ▂▄▆█        WPA2
abramshumps_5G                Infra  36    270 Mbit/s                69      ▂▄▆_         WPA1 WPA2
abramshumps                       Infra  13    270 Mbit/s                64      ▂▄▆_         WPA1 WPA2

cool - so wifi working out of the box this time - not going to have to go through pain of building drivers for my laptop (Dell Latitiude 7280)

so next lets see my wifi device:

root@bionic-beaver-x8664:~# ip link show
1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s31f6: mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether a4:4c:c8:21:7c:44 brd ff:ff:ff:ff:ff:ff
3: wlp2s0: mtu 1500 qdisc mq state DOWN mode DORMANT group default qlen 1000
    link/ether cc:2f:71:73:a3:3e brd ff:ff:ff:ff:ff:ff

we can try and connect to it now:

root@bionic-beaver-x8664:~# nmcli d wifi connect abramshumps password supersecretpw
Device 'wlp2s0' successfully activated with 'ead1b11c-3d70-4ba8-9ca9-48389235c7db'.

now lets test connectivity to internet:

root@bionic-beaver-x8664:~# ping
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=60 time=13.2 ms
64 bytes from icmp_seq=2 ttl=60 time=13.3 ms
--- ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 13.292/13.344/13.397/0.126 ms

yay - I can now add ubuntu-desktop and other goodies I want :-)

bash best practices

Bash best practices A few hints on bash best practice: * use #!/usr/bin/env bash .. this is more portable but you cant rely on a spe...