Skip to end of metadata
Go to start of metadata

Description

Apple announced changes to the default shell for macOS 10.15:

https://support.apple.com/HT208050

The current beta version of macOS 10.15 only affects newly created users.

Information

For years now, Apple have appeared to avoid any tools that are covered by the GPL v3 Licence as well as remove any that were in use over time.  Bash is one of these.  In the early releases of 10.x Apple initially used tcsh shell as default, but soon moved to bash; so this is not the first time Apple have made a change of this kind.  

In order to avoid newer versions of bash covered by GPL v3 licensing, it can be seen how old bash is on a macOS device:

$ bash -version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
Copyright (C) 2007 Free Software Foundation, Inc.

Run the same command on a modern Linux system, e.g. the FileWave Linux Server Appliance and you will see a much newer version:

$ bash -version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

GPL v3 licence has implications for Apple.  zsh is licensed under MIT, which does not involve these same implications.


Considerations

Specifying the shell

The first line of a script should indicate which shell is used when a script runs.

Example, for bash this could typically be either of the following (this is known as the 'shebang'):

#!/bin/bash
#!/usr/bin/env bash

By providing this, the script will run from a shell of the specified type.  Any scripts created should have this set.  If this is not set, then the script will run in the shell type that is currently set for that shell's session.  Apple's changes will have an impact on any scripts not specified by default.  Best practice is to always add the shebang at the beginning of any script to ensure expected behaviour.

Bash vs zsh

Bash and zsh are very similar, but there are some differences which may interfere with scripts that were written for bash, but are then run as zsh.  Scripts should therefore be analysed for behaviour if the shell type of the script is changed.

Examples

Arrays

The first item of an array differs when being referenced:

  • bash reference of first item in an array: index 0
  • zsh reference of first item in an array: index 1

There is also a difference in deleting items from an array.  The following produce the same output from the same original array, but note differences on the item being indexed and the method of removal:

bash arrays
#!/bin/bash


myarray=("one" "two" "three")
echo ${myarray[@]}
echo "First item in array: "${myarray[0]}

echo "Remove first item in array, item 0..."
unset myarray[0]
echo ${myarray[@]}

exit 0

# Script output:
one two three
First item in array: one
Remove first item in array, item 0...
two three
zsh arrays
#!/bin/zsh

myarray=("one" "two" "three")
echo ${myarray[@]}
echo "First item in array: "${myarray[1]}

echo "Remove first item in array, item 1..."
myarray[1]=()
echo ${myarray[@]}

exit 0

# Script output:
one two three
First item in array: one
Remove first item in array, item 1...
two three


Variable Expansion

Word splitting on variable expansion differs between bash and zsh.  For example, bash will print the following, one line per word, whilst zsh will print the whole variable as one line.  Note also, that bash, by default, will not expand aliases when the shell is not interactive, unlike zsh.

bash variable expansion
#!/bin/bash

# Expand aliases
shopt -s expand_aliases

alias printvar="printf '%s\n'"
myvar='one two'
printvar $myvar

exit 0

# Script output:
one
two
zsh variable expansion
#!/bin/zsh

alias printvar="printf '%s\n'"
myvar='one two'
printvar $myvar

exit 0

# Script output
one two

zsh does have the ability to set an option to change this behaviour, but consider converting to an array instead.

Apple has chosen zsh over bash, since the overlap on script compatibility is high.  However, as seen there can be differences and so it is prudent to check all scripts for behaviour.  The above are just examples; other differences may be experienced and will require addressing appropriately.