linux:bash-shell-scripting

Bash Shell Scripting

If you are running the script with `sh hello.sh`, the interpreting shell will not be the one mentioned in the shebang line, but `/bin/sh` will be used. In case of Debian and Ubuntu by default this will be `dash`.

So to run your script correctly with a `bash`, use either of the following.
1.)

    /bin/bash hello.sh

2.)
can't run a ./file.sh file, then run this command chmod +x filename.sh

    chmod +x hello.sh
    ./hello.sh

Alternatively you also could set `bash` as the `/bin/sh`.

    dpkg-reconfigure dash 

In general, you can use a backslash at the end of a line in order for the command to continue on to the next line. However, there are cases where commands are implicitly continued, namely when the line ends with a token than cannot legally terminate a command. In that case, the shell knows that more is coming, and the backslash can be omitted. Some examples:

# In general
$ echo "foo" \
> "bar"
foo bar

# Pipes
$ echo foo |
> cat
foo

# && and ||
$ echo foo &&
> echo bar
foo
bar
$ false ||
> echo bar
bar

Different, but related, is the implicit continuation inside quotes. In this case, without a backslash, you are simply adding a newline to the string.

$ x="foo
> bar"
$ echo "$x"
foo
bar

With a backslash, you are again splitting the logical line into multiple logical lines.

$ x="foo\
> bar"
$ echo "$x"
foobar

It is implicit

Unless you explicitly put a command into the background (using a single & character), the shell will wait for it to complete before execution proceeds to the next command

It's only if you want to ensure that a command completes successfully (i.e. exits with status 0) that you need to chain it to the next command with the && logical operator

You can write it on separate lines like this:

#!/bin/bash
apt-get clean && 
    cd /var/lib/apt && 
    mv lists lists.old_`date '+%Y%m%d_%H%M'` && 
    mkdir -p lists/partial && 
    apt-get clean && 
    apt-get update && 
    apt-get upgrade
echo 'Completed'

A cleaner way (in my opinion) is to do it like this:

#!/bin/bash
apt-get clean || exit 1
cd /var/lib/apt || exit 1
mv lists lists.old_`date '+%Y%m%d_%H%M'` || exit 1
mkdir -p lists/partial || exit 1
apt-get clean || exit 1
apt-get update || exit 1
apt-get upgrade || exit 1
echo 'Completed'
exit 0

This way you aren't chaining a bunch of commands together which can be confusing and difficult to read. The command after a || operator executes only if the command prior was not successful (or returns a non-zero return code)–the opposite of &&. The “exit 1” causes the script to exit at the point where something failed, and returns a 1 return code so a calling script will know if your script was successful.

It's also good convention to put “exit 0” at the end of your script to explicitly return a success return code, even though the shell will do this if you don't.

set DIR variable to current directory inside of the bash script

DIR="$(cd "$(dirname "$0")" ; pwd -P)"
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
  • linux/bash-shell-scripting.txt
  • Last modified: 2020/08/14 05:03
  • by jimboobrien