Is this an appropriate approach and layout for conditionally continuing execution in bash? I've seen others use &amp;&amp; for conditionally continuing execution in bash, and found it effective but rather ugly. (I'm not sure if there's a better name for this technique.)

do_something &amp;&amp; something_else &amp;&amp; the_next_thing


Then I found out that you can simply wrap things in parentheses just because you feel like it. (And in my original motivation was to return to easily return to the calling folder.)

So in the following script, I tried combining those techniques. (The motivation for the script is an attempt to install RabbitVCS for development.)

Questions:


is combining &amp;&amp; and () in this way "idiomatic" for bash?
similarly, is using () to return to the calling folder appropriate
how's my indentation? (I normally program in Python ;) )


    #! /bin/bash

    # CC0 To the extent possible under law, the person who associated CC0
    # with this work has waived all copyright and related or neighboring
    # rights to this work. https://creativecommons.org/publicdomain/zero/1.0/

    # Required folders (must exist beforehand):
    #  * Source code and script folders (see export statements below)
    #  * Nautilus 3: ~/.local/share/nautilus/python-extensions
    #  * CLI: /usr/bin (always exists)
    #  * GEdit: ~/.local/share/gedit/plugins

    # Out of scope for this script:
    #  * Setting up folders above
    #  * Keeping RabbitVCS source code up-to-date

    # Set customisable folder paths:
    # Source code, cloned from GitHub
    export SOURCE_FOLDER=~/Code/rabbitvcs
    # User scripts location for RabbitVCS CLI (must be in .bashrc or equivalent)
    export SCRIPT_FOLDER=~/Code/scripts

    if [ "$1" = "--help" ] || [ -z $1 ] || [ "$2" ];
    then

        # if "--help" is called, or too many or too few parameters given, display help
        echo "Install specified branch of RabbitVCS with Nautilus, Gedit and CLI clients."
        echo "(Assumes prerequisites are installed and target branch and folders exist.)"
        echo "Usage: install-rabbitvcs-branch "

    else
        ( # parentheses so that we return to original folder

            # install all prerequisites, even the obvious ones
            # (package names as used in Ubuntu 13.10)
            # (also triggers prompt for sudo password as soon as possible)
            sudo apt-get install gedit git hicolor-icon-theme ipython meld subversion python python-configobj python-dbus python-dulwich python-gobject python-gobject-2 python-gtk2 python-gtkspell python-nautilus python-simplejson python-support python-svn -qq && (

                # kill existing Nautilus and RabbitVCS processes (if they exist)
                pgrep -f nautilus && nautilus -q
                pgrep -f service.py && xargs kill

                # checkout requested branch
                cd $SOURCE_FOLDER && git checkout $1 && (

                    # (re)install RabbitVCS library
                    sudo python setup.py check && sudo python setup.py install && (

                        # (re)install RabbitVCS clients
                        echo "Installing RabbitVCS clients..."
                        cp clients/nautilus-3.0/RabbitVCS.py ~/.local/share/nautilus/python-extensions
                        cp clients/gedit/rabbitvcs-plugin.py ~/.local/share/gedit/plugins
                        cp clients/gedit/rabbitvcs-gedit3.plugin ~/.local/share/gedit/plugins
                        cp clients/cli/rabbitvcs $SCRIPT_FOLDER
                        echo "done."
                    )
                )
            )
        )
    fi
Firstly, this will most likely do a wrong thing if the first argument is empty:

if [ "$1" = "--help" ] || [ -z $1 ] || [ "$2" ];


You should probably use something like this instead (note added quotes):

if [ "$1" = "--help" ] || [ -z "$1" ] || [ $# -gt 1 ];


In general you should quote all variables which are not guaranteed to be set, to be non-empty and to only contain alphanumeric characters.

Secondly, I would not call myself a seasoned bash hacker, but parenthesis are imo more common if you need to run a small command in another directory, e.g.

(cd -P "$anotherdir"; make fun)


When it comes to longer code pieces you can either use a function or simply pushd and popd, e.g.

pushd .
cd "$anotherdir"
# do something else
popd


As for formatting, I also use four-space indentation but prefer more dense code and therefore put then on the same line as if. Additionally, I usually write following code if I need several commands to run in sequence only if everything worked out fine:

stderr() {
    cat - 1&gt;&amp;2
}

fail() {
    printf "%s\n" "$@" | stderr
    return 1
}

commandA "$arg1" "$arg2" || fail "ERROR: something went wrong"
commandB "$arg1" "$arg2" || fail "ERROR: something else went wrong"


UPDATE: Incorporate rolfl's suggestion to use a fail() function.