Bash Error Output

Bash Error Output

Bash provides I/O redirection. There are 3 standard files: STDIN (standard input) with descriptor 0, STDOUT (standard output) with descriptor 1, and STDERR (standard error) with descriptor 2.

If you want to redirect your messages to STDERR, you can use >&2 symbol. This symbol is abbreviation of 1>&2 symbol which means, that everything in STDOUT will go to STDERR.

So, if you want to put the message “Cannot delete directory” in STDERR, you can do it this way:

echo Cannot delete directory >&2

Even more, you might to create your own function for error messages:

recho() { echo "$*" >&2 ; }
recho "Cannot delete directory" > /dev/null

Output: Cannot delete the directory

On the first line, we define recho function (error echo). This function will print all its arguments ($*) to STDERR (>&2).

On the second line, we try to use the function. To prove, that output will be written to STDERR, we will redirect STDIN to nowhere (/dev/null). So, if you see some output, it should be in STDERR.

Bash How to Trim String

Bash How to Trim String

You can use a bash parameter expansion, sed, cut, and tr to trim a string.

Let’s use bash parameter expansion to remove all whitespace characters from the variable foo:

foo="Hello world."
echo "${foo//[["space:]]/}"

Output: Helloworld.

“${foo// /}” removes all space characters, “$foo/ /” removes the first space character.

To remove only space characters before and after string use sed:

foo=" Hello world. "
echo "${foo}" | sed -e 's/^[[:space:]]*//'

Output: Hello world.

Easy to use and remember the way how to remove whitespaces before and afterword:

echo " text. text2 " | xargs

xargs remove all whitespaces before “text.” and let one space between text. and text2.

If you want to delete only the last character from the variable:

foo="hello"
echo "${foo::-1}"

Output: hell

What is Bash

What is Bash

Bash is a program (toolbox) used to interact between user and operating system.

The BASH acronym is for the ‘Bourne-Again SHell’. Bash is one of many shells, or command language interpreters, in Unix system.

I called bash a “toolbox”, because it contains large variety of shell tools, for example, tools for read files, calculate math operations, control devices…

The main difference between bash and any other program is that bash was not created to process certain task. Bash was developed to take commands from user using the text-based interface.

One of the advantages of bash is that users can put list of commands to a one (script) and execute these commands from file.

Most of bash scripts have ‘.sh’ extension, for example: script.sh. Linux is an extensionless system, but it is good practice to add .sh extension.

Bash Hello World Script

Bash Hello World Script

This bash example creates an archive from /home directory to /backup/ directory as one tar.gz file. Let’s create a file backup.sh. It will consist of two lines:

#!/bin/bash
tar -czf /var/home-backup.tar.gz /home/

First line is a hashpling. Basically, it says who execute script. In this example, we choose /bin/bash.

The second line is tar command. It tarballs and compress the whole directory (/home) to one file.

I recommend you give also the third line (empty line). Why? If you execute this script in unusual UNIXes (ec. SCO UNIX), UNIX coudn’t execute last line, becasuse last symbol of file – EOF (end of file) is different from symbol EOLN (end of line). Symbol EOLN (enter) or semicolon (;) executes command.

Would you to extend this script to some output? Here is an example.

#!/bin/bash
echo -n Creating backup of home directory to /backup...
tar -czf /var/home-backup.tar.gz /home/ >/dev/null 2>&1
echo done.

On the second line, echo with n parameter doesn’t give a new line.

On the third line, output from tar command is redirected to trash (/dev/null).

Last line, just echoes done.

If you don’t know what to put on the first line (hashpling) type:

echo $SHELL

Output: /bin/bash

You will get path to your shell, which can use in the hashspling.

Bash Scripting Best Practices

Bash Scripting Best Practices

Let’s begin with the first line of your script. The first rule always starts script with shebang. Without the shebang line, the system does not know which shell to process. For example:

#!/bin/bash

After shebang line write what is your script about and what it would do.

For debugging printout run your script with the “-x” or “-v” option like:

bash -x script.sh

Use the set lines:

set -e

set -u

set -o pipefail

“-e” to immediately exit if any command has non-zero exit status. “-u” causes the program to exit when you haven’t previously defined variable (except $* and $@). Option “-o pipefail” prevents fails in a pipeline from being masked. The exit status of the last command that threw non-zero exit code is returned.

Never use backticks, use:

$( ... )

Back-ticks are visually similar to single quotes, in a larger script with hundreds of lines you could be confused if it is back-ticks or single quotes.

If you need to create temporary files, use “mktemp” for temporary files and cleanup with “trap”.

Bash Vs KSH

Bash Vs KSH

Linux and Unix have various shells. Two kinds of these numerous shells are KSH and BASH.

KSH (The Korn Shell) was developed many years before the BASH. Ksh has associative arrays and handles loop syntax better than bash. Also, ksh’s command print is better than bash’s echo command. In other way, ksh does not support history completion, process substitution, and rebindable command-line editing.

Bash has more added extension than ksh. Bash has tab completion and an easier method to set a prompt in order to display the current directory.

Compared to ksh, bash is newer and more popular.

Example of difference ksh and bash in condition test. First bash:

if [ $i -eq 3 ]

and condition test in ksh:

if (($i==3))

Bash can handle exit codes from pipes in a cleaner way. Bash and KSH are both Bourne=compatible shells, they share common functions and features and can be interchangeable to use.

Bash How to Basename

Bash How to Basename

Command basename strip directory and suffix from filenames. Command syntax:

basename [option] name [suffix]

If the suffix is specified it will remove a trailing suffix. Example:

basename dir1/dir2/dir3/text_file.txt .txt

Output: text_file

Basename takes one argument (filename) and an optional suffix. If you want to give more file names use the option “a” which supports multiple arguments and threat each as “name”.

basename -a /dir/file.txt /dir2/picture.jpg

Output: file.txt picture.jpg

If you want to get the name of your home folder:

basename ~

Often used option is option -s which removes a trailing suffix. Here is an example:

basename -s .txt -a /dir/file.txt /dir2/picture.jpg

file picture.jpg

Bash How to do Math

Bash How to do Math

You can use arithmetic expansion with parentheses or square brackets:

a=0
echo $((a+5))

Output: 5

echo $[a+2]

Output: 2

Another option is using the command “bc”:

echo "5+3" | bc

Output: 8

If you need to do math with a float number, use the variable “scale” to define how operations use decimal numbers

echo "scale=2; 1/4" | bc

Output: 0.25

Evaluate expression with only integer you can use the command “expr”

echo `expr 10 - 2`

Output: 8

Be careful with multiply operations. Always escape * (asterisk) char with \. For example:

expr 5 \* 3

Output: 15

Bash How to List Environment Variables

Bash How to List Environment Variables

If you want to print all environment variables, you can use printenv. Command printenv print all or just part of environment variables:

printenv

If you want to get names of variables, that was exported, you can use the export command:

export

You can use also the just env command. If you want to see all environment variables:

env

In fact, env run some program in a modified environment. In the next example, env will run only with a variable called “DIRECTORY”:

env -i DIRECTORY="/etc/mydir" bash
env

If you want to see functions, that you have declared, you can use “declare -f”. Maybe you have not defined any function. To overcome this, in the next example, we defined FUNKY_FUNCTION first:

FUNKY_FUNCTION ()
{
echo ":-)"
}
declare -f

The next command includes shell variables to output:

( set -o posix ; set ) | less

This command shows not only shell variables, but environment variables too.

Bash How to Pass Arguments

Bash How to Pass Arguments

The special shell variable “$@” represents a list of all arguments that is passed to the script.

If you want to pass all arguments to your function, you can use this syntax:

function_name "$@"

If you want to pass all arguments to another script, you can use this syntax:

script_mame "$@"

Let’s take an example called passit.sh. In this script, we defined function print_argument, that print argument that comes from the command line:

#!/bin/bash

# function's definition
function PRINT_ARGUMENTS()
{
echo "Arguments of shell are: $@"
}

# in this place we want to call function
PRINT_ARGUMENTS "$@"

Let’s try to execute passit.sh in this way:

chmod u+x ./passit.sh
./passit.sh aa bb cc

Output: Arguments of the shell are: aa bb cc

You can see that function obtains all shell arguments, which were written in the bash command line.

To get a number of arguments use:

echo "Number of arguments of shell are: $#"

It is often used to check if a required number is equal to some value.

Bash Color Shell Prompt

Bash Color Shell Prompt

You can customize 4 prompts: PS1 (Primary prompt, displayed before each command), PS2 (secondary prompt, displayed when a command needs more input), PS3 (rarely used, displayed for Bash’s select built-in which displays interactive menus).

Display current bash prompt (PS1) settings:

echo $PS1

Output: [\u@\h \W]\$

It is the default setting. The backslash-escaped characters means: \u (username), \h (hostname), \W (current working directory).

To modify colors to the prompt use following syntax:

\e[x;ym $PS1 \e[m

Meaning: \e[ (start color scheme), x;y (color pair to use), $PS1 (shell prompt variable), \e[m (stop color scheme)

To set red color enter:

export PS1="\e[0;36m[\u@\h \W]\$ \e[m "

Few examples of color codes:

  • black(0;30)
  • red (0;31)
  • greed (0;32)
  • brown (0;33)
  • blue (0;34)
  • purple (0:35)
  • cyan (0:36)

If you replace digit 0 with 1 you get a lighter color version.
Setting variable PS1 is temporary, when you log out your settings will be lost. You have to append the following line to $HOME/.bash_profile file or $HOME/.bashrc file:

export PS1="\e[0;36m[\u@\h \W]\$ \e[m "

Now ur new prompt color is permanent.