Bash Error Output Redirect

Bash Error Output Redirect

Each open file gets assigned a file descriptor. The file descriptors for STDIN is 0, for STDOUT is 1 nad STDERR is 2.

If you want to redirect just STDERR (standard error output) to file, ju do:

cmd_name 2> /file

If you want o redirect STDOUT to other files, and STDERR to other files, just do:

cmd_name >/stdout_file 2>/stderr_file

If you want to merge both (STDERR, STDOUT) into one file, you can do:

cmd_name >/file_4_both 2>&1

For the same effect, you can also use this syntax:

cmd_name &> /file_4_both

Even more, it is very useful to use the tee command. By definition, tee read from standard input and write to standard output and files, in same time.

In next example, we merge STDOUT and STDERR of “find /” command together. Then, we pass it to STDIN of tee command. Tee command is executed with -a parameter, that means append to an existing file (if exists):

find / 2>&1 | tee -a /home/tee.output
ll /home

Output: (lines omitted) -rw-r–r–. 1 root root 2.2M Jun 10 13:16 tee.output

The child process inherits open file descriptors. If you want to prevent file descriptors from being inherited, close it. For example:

<&-

This close stddin descriptor.

What is Bash Script

What is Bash Script

Metaphorically speaking bash script is like a ‘to-do list’. After you read the first entry you start realizing it. After you finished first entry, you continue with the second entry and so on.

A bash script is a text file that contains a mixture of commands.

Bash script can contain also functions, loops, conditional constructs. Scripts are commonly used for administration task like change file permission, creating disk backups. Using bash scripts is often faster than using the graphical user interface.

It’s important to mention that there is no difference between putting series of 10 commands into a script file and executing that script or you entering commands one by one to the command-line interface. In both situations, the result will be exactly the same thing.

After you create your script it is good practice to add the extension ‘.sh’ to the filename, for example ‘myFirstScript.sh’.

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.