Skip to content
Search

Bash:Example

lastmod 2024-07-25created 2015-10-2041 edits

A summary of simple usage of Bash.

Categories

Debugging

How to debug Bash is as follows.

set -x
## OR
set -v

## 원상복구
set -

Checking root privileges

Require root privileges:

if [[ $(id -u) -ne 0 ]]; then
    echo 'Please run as root.'
    exit 1
fi

Disallow root privileges:

if [[ $(id -u) -eq 0 ]]; then
    echo 'Please do not run as root.'
    exit 1
fi

Check if sudo

if [ "$(whoami)" != "root" ]; then
    echo "Sorry, you are not root."
    exit 1
fi

or

## $(id -u) == $EUID
if [[ $(id -u) -ne 0 ]] ; then echo "Please run as root" ; exit 1 ; fi

Index Rename

IDX=0; for i in *.jpg; do mv "$i" "${IDX}.jpg"; let "IDX = IDX + 1"; done

Checking the Linux distribution

lsb_release -r | awk '{print $2}'

Or check it as follows.

cat /etc/*-release | grep -E '^ *NAME *='

See the lsb_release command.

Disable beep sound

echo 'set bell-style none' >> ~/.inputrc

Or open the /etc/profile file and add the following line.

echo -ne '\033[11;0]'

#!

Whereis

To find the full path of a particular file, enter the following.

which sh

For reference, the code that does the same thing in cmd is as follows.

where sh

User input

You can get user input as follows.

# USER_TEMP 변수에 사용자 입력값을 적용한다.
read USER_TEMP

# 1 글자만 입력 받는다.
read -n 1 USER_TEMP

# 미리 문자열을 출력한다.
read -p "Repository username: " USER_TEMP

# 보안속성을 추가한다. (사용자 입력이 출력되지 않는다)
read -s -p "Repository password: " USER_TEMP

For reference, you can confirm YES/NO as follows.

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

Using a variable name as an argument (${!param})

variable=255.255.255.255
param=$1
echo ${!param}

then execute:

bash script.sh variable
255.255.255.255

Command-line user input

Sometimes you want to pass user input on the command line, for example from a script.

First, given a file like the following:

# test.sh
$ read value
$ echo '1: ' $value
$ read value
$ echo '2: ' $value
$ read value
$ echo '3: ' $value

use it as follows.

$ echo -e 'a\nb\nc' | ./test.sh

How to iterate over arguments

INDEX=1
SIZE=$#
while [[ $INDEX -le $SIZE ]]; do
    echo $1
    let 'INDEX = INDEX + 1'
    shift
done

The eval builtin command

To enter a Bash command directly, use the eval command.

$ eval "export NAME='VALUE'"

Input LOOP via PIP

You can provide an input loop via PIP as follows.

command | while read -r line; do
  command "$line"
done

Checking the EXIT CODE

The last EXIT CODE can be checked as follows.

$ echo $?

Code depending on existence (Exist)

To check if a directory exists in a bash shell script you can use the following:

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists
fi

# Or to check if a directory doesn't exist:
if [ ! -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY doesn't exist
fi

# In Cshell:
if ( ! -e $DIRECTORY ) then
    # Will enter here if $DIRECTORY doesn't exist
endif

# check if a file doesn't exist:
if [ ! -f /tmp/foo.txt ]; then
    echo "File not found!"
fi

Printing script contents (debugging)

Setting set -x for debugging prints all of the script's contents. To print whether debugging is on, check as follows.

if [[ "$-" == *x* ]]; then
  echo "is set"
else
  echo "is not set"
fi

Filling a whole line with "-"

Detects the terminal width by reading the value of the COLUMNS variable. (If that variable is not set, tput is used.)

cols=${COLUMNS:-$(tput cols)}

## "-"로 한 줄을 채웁니다.
printf -v line '%*s' "$cols" ''
echo "${line// /-}"

Expansion of variable inside single quotes

How to add an environment variable inside quotes is as follows.

'before'"$variable"'after'
'before'\''after'
'before'"'"'after'

User defined function

function e {
    echo $1 
}

Platform checker

To identify the OS currently in use, do the following.

case "$(uname -s)" in
   Darwin)
     echo 'Mac OS X'
     ;;
   Linux)
     echo 'Linux'
     ;;
   CYGWIN*|MINGW32*|MSYS*)
     echo 'MS Windows'
     ;;
   *)
     echo 'other OS (or missing cases for above OSs)' 
     ;;
esac

Function object

Function objects can be created and used as follows.

#!/bin/sh

function test1 {
    echo FUNCTION_TEST1
}
function test2 {
    echo FUNCTION_TEST2
}

declare -a VAL
VAL[0]=test1
VAL[1]=test2

function run {
    local index=$1
    ${VAL[$index]}
}

run 0
run 1

Date format

The current date and time format for file names is as follows.

DATE_FORMAT=`date +%Y%m%d_%H-%M-%S`

STDOUT and STDERR

You can add color to STDERR output as follows.

function stdout { echo "$@" }
function stderr { echo -e "\033[31m$@\033[0m" 1>&2; }

stdout 'STDOUT Message'
stderr 'STDERR Message'

Current file

__FILE__="${BASH_SOURCE[0]}"
echo $__FILE__

Current directory

How to get the parent directory path of the invoked script file is as follows.

SCRIPT_DIR="$( cd "$(dirname ${BASH_SOURCE[0]})" ; pwd -P )"

Note that using it as above changes the directory path, so be careful.

MD5 checksum result

MD5_CMD=`if [[ $(uname -s) == Darwin ]]; then echo 'md5 -r'; else echo 'md5sum'; fi`
CHECKSUM=`$MD5_CMD test_file_path | awk '{print($1);}'`

Upper and Lower

The syntax is as follows.

  • lower case: ${parameter,,pattern}
  • UPPER CASE: ${parameter^^pattern}
$ string="Hello, World!"
$ echo $string
Hello, World!
$ echo ${string,,}
hello, world!
$ echo ${string^^}
HELLO, WORLD!

How to obtain the number of CPUs/cores

## Darwin:
$ sysctl -n hw.ncpu

## Linux:
grep -c ^processor /proc/cpuinfo

## Windows:
$ echo $NUMBER_OF_PROCESSORS
## OR (winbatch):
$ WMIC CPU Get NumberOfLogicalProcessors

Split string loop

sentence="one;two;three"
sentence=${sentence//;/$'\n'}  # change the semicolons to white space
for word in $sentence
do
    echo "$word"
done

Find string

function findString {
    local string=$1
    local find=$2
    local size=${#string}

    for ((i = 0; i < $size; i++)); do
        if [[ "${string:$i:1}" == "$find" ]]; then
            break;
        fi
    done
    echo $i
}

Reverse find string

function rfindString {
    local string=$1
    local find=$2
    local size=${#string}

    for ((i = $size; i >= 0; i--)); do
        if [[ "${string:$i:1}" == "$find" ]]; then
            break;
        fi
    done
    echo $i
}

For reference, characters such as tab (\t) can be used as follows.

index=`findString $path $'\t'

File extension

How to get a file's extension is as follows. Requires the rfindString function above.

function getExtension {
    local name=$1
    local index=`rfindString $name '.'`
    echo ${name:$index}
}

For a simpler method, see here.

Remove file list

A script that removes files existing in a given directory (SRC_DIR) if they also exist in the target directory (DEST_DIR) is as follows.

WORKING=$PWD
SRC_DIR=train_fire_backup/
DEST_DIR=train/

for path in $SRC_DIR*; do
    echo $path | sed "s;.*/;$DEST_DIR;g" | xargs rm
done

Rename file index

How to rename files in INDEX order is as follows.

WORKING=$PWD
SRC_DIR=train/
DEST_DIR=train2/

if [[ ! -d "$DEST_DIR" ]]; then
    mkdir $DEST_DIR
fi

INDEX=0

for path in $SRC_DIR*.jpg; do
    let "INDEX = INDEX + 1"
    mv $path ${DEST_DIR}${INDEX}.jpg
done

Extract directory

Compresses every directory in the current location individually.

for i in $(find . -type d -depth 1); do printf "%s\n%s\n" "$i.tar.gz" "$i" | xargs -n 2 tar czf; done

Dynamic variable names

var=name_of_var
echo $(eval echo "\$$var")

Multi-line string

How to assign a string value across multiple lines

text="this is line one
this is line two
this is line three"
echo "$text" > filename

Piping command output to tee but also save exit code of command

mvn clean install $@ | tee $logfile
echo ${PIPESTATUS[0]}

Favorite site

author Zer0 sitemap