Umount: Force – Target | Device is Busy

An umount command is used to unmount a device/partition by specifying the path to the directory where it has been mounted.

Sometimes, when you run the umount command you may receive the “target is busy” or “device is busy” errors indicating that there is some process that is using the mounted filesystem or the remote file server is not responding for some reason.

Luckily, it is possible to run the umount command forcefully and this short note shows how to do this safely. (more…)

Git Bash: Clear History

The history -cw command is used to clear a Bash history on Linux, but for some reason it doesn’t work for a Git Bash on Windows.

If you try to clear the commands history in the Git Bash using this command, it won’t work – you will still see the history of the executed commands after the application restart.

To completely erase the Git Bash history you need to locate and delete the .bash_history file and then run the history -c command. (more…)

Mass Emails Sending From Bash Script in Linux

To prevent abuse and don’t allow to send bulk emails through SMTP server, it is recommended to restrict the number of messages that each user can send.

Let’s say we have limited the number of messages to send, but how can we check that the limitation works?

The best way to make such check is to try to send mass emails, as spammers usually do, using our SMTP server as relay.

From the Linux Command Line, we can create a simple Bash Script that can send multiple emails for testing purposes.

Sending Bulk Emails for Testing Purposes

Use the following Bash Script from your Linux machine to send 1000 emails to example@mail.tld:

#!/bin/bash
for i in {1..1000}; do
	echo "Test" | $(which mail) -s "Test Message №$i" "example@mail.tld"
done

Bash: String Length – How To Find Out

If you often create Bash scripts, you may sometimes need to get the length of a string or find out the length of a variable that stores some string.

This short note shows how to find out the length of a string from the Linux command line and how to count the length of the each line in a file.

You will also see how to get the length of a string if it is stored in a variable in Bash and then assign that calculated number of characters to another variable. (more…)

“Yes/No” in Bash Script – Prompt for Confirmation

Very often in bash scrips you need to ask for user input that requires a Yes or No answer.

For example, you may want to put a quick “Are you sure?” prompt for confirmation before execution of some potentially dangerous part of a bash script.

In this article you’ll find three easiest and fastest ways to prompt for “Yes/No” confirmation in bash script.

Prompt To Continue In Bash

The best way to prompt for a confirmation to continue in a bash script is to use the read command (source):

read -p "Are you sure? " -n 1 -r
echo    # (optional) move to a new line
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
    exit 1
fi

Simple “Yes/No” Dialog In Bash

One of the most widely used method to ask user for a confirmation in a bash script is to combine read + case commands (source):

while true; do
    read -p "Do you wish to install this program?" yn
    case $yn in
        [Yy]* ) make install; break;;
        [Nn]* ) exit;;
        * ) echo "Please answer yes or no.";;
    esac
done

Select From “Yes/No” Menu In Bash

Another easy method is to use select command (source):

echo "Do you wish to install this program?"
select yn in "Yes" "No"; do
  case $yn in
    Yes ) make install;;
    No ) exit;;
  esac
done

CASE Statement in Bash [Example]

The following article describes the basic syntax and includes a simple example of the BASH CASE statement usage.

The CASE statement is the simplest form of the IF-THEN-ELSE statement in BASH.

You may use the CASE statement if you need the IF-THEN-ELSE statement with many ELIF elements.

With the BASH CASE statement you take some value once and then test it multiple times.

Basic Syntax of the CASE Statement

case $variable in
     pattern-1)      
          commands
          ;;
     pattern-2)      
          commands
          ;;
     pattern-3|pattern-4|pattern-5)
          commands
          ;; 
     pattern-N)
          commands
          ;;
     *)
          commands
          ;;
esac

Example of a BASH Script with the CASE Statement

#!/bin/bash
printf 'Which Linux distribution do you know? '
read DISTR

case $DISTR in
     ubuntu)
          echo "I know it! It is an operating system based on Debian."
          ;;
     centos|rhel)
          echo "Hey! It is my favorite Server OS!"
          ;;
     windows)
          echo "Very funny..."
          ;; 
     *)
          echo "Hmm, seems i've never used it."
          ;;
esac

Run the script as follows:

$ ./testcase.sh
Which Linux distribution do you know? centos
Hey! It is my favorite Server OS!
$ ./testcase.sh
Which Linux distribution do you know? rhel
Hey! It is my favorite Server OS!
$ ./testcase.sh
Which Linux distribution do you know? ubuntu
I know it too! It is an operating system based on Debian.
$ ./testcase.sh
Which Linux distribution do you know? pfff
Hmm, seems i've never used it.

Print Usage and Exit if Arguments are Not Provided

Use the following test in your shell scripts to:

1. verify the number of input values

2. display an error message if the number of input argument is not correct

3. exit a shell script with the error status

[ $# -eq 0 ] && { echo "Usage: $0 argument"; exit 1; }
Parameter Description
$# variable tells the number of input arguments the script was passed
-eq 0 check if the number of input arguments is equal zero
$0 returns the path to your shell script

Bash Script Example

The following script is using dig command to find the name server of a domain name. The domain name should be provided as an argument.

#!/bin/bash
domain=$1
[ $# -eq 0 ] && { echo "Usage: $0 domain_name"; exit 1; }
dig NS $domain @8.8.8.8 +short

Sample output if no arguments are specified :

$ ./find_ns.sh
Usage: ./find_ns.sh domain_name

Sample output if an argument is passed:

$ ./find_ns.sh shellhacks.com
ns2.ukraine.com.ua.
ns3.ukraine.com.ua.
ns1.ukraine.com.ua.

7 Tips – Tuning Command Line History in Bash

7 Tips that can help you to improve you Bash history file.

You will learn how to add date and time to bash history file, increase history size, ignore specific commands and much more …

Every command that you enter, is stored in the file ~/.bash_history. Run history to see your last commands.

You can improve your Bash history, appending different environment variables to your ~/.bashrc file.

After modifying ~/.bashrc file, execute the following command to apply changes:

source ~/.bashrc

1. Add Date and Time to Bash History

Sometimes it would be very nice to know when some command got executed.

Set HISTTIMEFORMAT to print the time stamps associated with each history entry.

Append the following line to ~/.bashrc file:

export HISTTIMEFORMAT="%h %d %H:%M:%S "

Now, when you type history, it will show something like:

113  Jun 08 16:31:06 sudo ifconfig
114  Jun 08 16:31:10 top
115  Jun 08 16:31:19 ping 8.8.8.8
116  Jun 08 16:31:22 history

2. Increase Bash History Size

Increase HISTSIZE – the number of commands to remember in the command history (the default value is 500).

export HISTSIZE=10000

Increase HISTFILESIZE – the maximum number of lines contained in the history file (the default value is 500).

export HISTFILESIZE=10000

3. Append Bash Commands to History File

Bash overwrites .bash_history file?

To append commands to the history file, rather than overwrite it, add the following line to ~/.bashrc:

shopt -s histappend

4. Store Bash History Immediately

By default, Bash only records a session to the .bash_history file when the session terminates.

This means that if you crash or your session terminates improperly, you lose the history up to that point.

Use $PROMPT_COMMAND variable to save each command right after it has been executed.

Append the following line to ~/.bashrc file, if the variable $PROMPT_COMMAND hasn’t been set yet:

PROMPT_COMMAND='history -a'

Append the following line, if the variable $PROMPT_COMMAND has already been set:

PROMPT_COMMAND='$PROMPT_COMMAND; history -a'

5. Control Bash History

HISTCONTROL is a colon-separated list of values controlling how commands are saved in the history file.

Value Description
ignorespace don’t save lines which begin with a <space> character
ignoredups don’t save lines matching the previous history entry
ignoreboth use both ‘ignorespace’ and ‘ignoredups’
erasedups eliminate duplicates across the whole history

Example:

export HISTCONTROL=ignorespace:erasedups

6. Ignore Specific Commands

HISTIGNORE is a colon-separated list of patterns used to decide which command lines should be saved in the history file.

Don’t save ls, ps and history commands:

export HISTIGNORE="ls:ps:history"

Don’t save commands with s in the beginig:

export HISTIGNORE="s*"

7. Use one command per line

Store multi-line commands in one history entry:

shopt -s cmdhist

Change the History File Name

Use HISTFILE to change the name of the file in which Bash history is saved. The default value is ~/.bash_history.

export HISTFILE=~/.custom_file

HowTo: Clear BASH History

Sometimes you don’t want to leave Bash history, because it may contain some sensitive data (e.g. passwords, tokens, etc.).

This article will help you to take a full control on your .bash_history file.

I will show how to clear the commands history for the current Bash session, how to prevent particular commands from being recorded to the .bash_history file and how to completely erase the Bash history. (more…)