Главная >> Информация >> Примеры Bash скриптов

Примеры Bash скриптов

Существует достаточное количество оболочек, например - sh, zsh, ksh и другие. Но мы остановимся на Bash, ведь это самая популярная оболочка среди Linux. Теперь даже Microsoft добавила поддержку Bash.

Эта статья предназначена для тех кто хоть немного знаком с языком сценариев Bash. Давайте рассмотрим некоторые примеры Bash скриптов, которые могут быть полезными в вашей повседневной работе.


Содержание статьи

Примеры Bash скриптов в Linux

Чтобы посмотреть какой интерпретатор команд у вас используется введите команду:

echo $SHELL

Shell

Как видите у меня установлен именно Bash.

1. Первая программа. Модификация команды 'rm'

#!/bin/bash
dir="$HOME/.archive/" # directory for deleted files
if [ -d $dir ]; then # check the directory .archive/
file="$1"
null=""
else mkdir $dir | chmod 700 $dir # if there is no, create
fi
if [ $file == $null ]; then # error, if not specified file #
echo -e "/!\  No file.. Usage: $0 filename ;-) | archive directory - $dir  /!\ "
exit 1
fi
mv $file $dir$(date "+%H.%d.%m").$file # move file to .archive/

Все мы знаем что делает команда rm, она удаляет файлы. Эта программа создает папку ~/.archive. Далее проверяет задан ли аргумент. Без аргумента программа выдаст сообщение об ошибке и прекратит работу. Если ей передан путь к файлу, она помещает его в директорию ~/.archive и добавляет дату(час,день,месяц) в начало имя файла, чтобы мы могли понять когда удалили файл.

Далее я приведу еще несколько программ, но без обяснений. Эти программы можно модифицировать, улучшать как угодно. Попробуйте написать что-то свое.

2. Проверка наличия пути к программе в переменной PATH

#!/usr/bin/bash
in_path() {
cmd=$1 ourpath=$2 result=1
oldIFS=$IFS IFS=":"
for directory in "$ourpath"
do
if [ -x $directory/$cmd ]; then
result=0
fi
done
IFS=$oldFS
return $result
}
##########
4ck() {
var=$1
if [ "$var" != "" ]; then
if [ "${var:0:1}" = "/" ]; then
if [ ! -x $var ];then
return 1
fi
elif ! in_path $var "$PATH" ; then
return 2
fi
fi
}
##############################
if [ $# -ne 1 ]; then
echo "Usage: $0 command" >&2
exit 0
fi
4ck "$1"
case $? in
0 ) echo "[$1] found in PATH" ;;
1 ) echo "[$1] not found or not executable" ;;
2 ) echo "[$1] not found in PATH" ;;
esac
exit 0
#############################

3. Нормализация вывода даты

#!/bin/bash
monthto() {
case $1 in
1 ) month="Jan" ;; 7 ) month="Jul" ;;
2 ) month="Feb" ;; 8 ) month="Aug" ;;
3 ) month="Mar" ;; 9 ) month="Sep" ;;
4 ) month="Apr" ;; 10 ) month="Oct" ;;
5 ) month="May" ;; 11 ) month="Nov" ;;
6 ) month="Jun" ;; 12 ) month="Dec" ;;
* ) echo "$0: Unknown month value $1" >&2 exit 1
esac
return 0
}
#################
if [ $# -ne 3 ] ; then
echo "Usage: $0 month day year" >&2
echo "Formats are August 3 1962 and 8 3 1962" >&2
exit 1
fi
if [ $3 -le 99 ]; then
echo "$O: expected 4-digit year value." >&2
exit 1
fi
if [ -z $(echo $1|sed 's/[[:digit:]]//g') ]; then
monthto $1
else
month="$(echo $1 | cut -c1 | tr '[:lower:]' '[:upper:]')"
month="$month$(echo $1 | cut -c2-3 | tr '[:upper:]' '[:lower:]')"
fi
echo $month $2 $3
exit 0

4. Создание библиотек сценариев

Библиотеки - это сценарии которые можно включать в другие сценарии.

colors()
{
esc="\033" ;
# text
blackf="${esc}[30m"; redf="${esc}[31m"; greenf="${esc}[32m";
yellowf="${esc}[33m"; bluef="${esc}[34m"; purplef="${esc}[35m"; cyanf="${esc}[36m"; whitef="${esc}[37m" ;
# backg
blackb="${esc}[40m"; redb="${esc}[41m"; greenb="${esc}[42m" ;
yellowb="${esc}[43m"; blueb="${esc}[44m"; purpleb="${esc}[45m" ; cyanb="${esc}[46m"; whiteb="${esc}[47m" ;
# bold, italic, etc...
boldon="${esc}[1m"; boldoff="${esc}[22m";
italicson="${esc}[3m"; italicsoff="${esc}[23m" ;
ulon="${esc}[4m"; uloff="${esc}[24m" ;
invon="${esc}[7m"; invoff="${esc}[27m" ;
reset="${esc}[0m" ;
}

Такие сценари можно легко включить в другой файл командой source и вызвав нужную вам фунцию.

Заключение

Сегодня мы разобрали несколько примеров Bash скриптов. Узнали как их исползовать в виде библиотечных сценариев. Очень много полезного можно написать на Bash, ограничение тому лишь ваше воображение. Но на самом деле, тема Bash скриптов велика и есть целые книги посвященные этой теме. Надеюсь статья была полезна. Про основы работы с Bash вы можете прочитать здесь.

Creative Commons License
Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .

6 комментариев к “Примеры Bash скриптов”

  1. Сегодня ничего мы не разобрали...
    кроме как узнали что там у нас за интерпретатор а дальше
    я просто деранул с нета пару "примеров" но что там я сам не в курсе ребята...

    Ответить
  2. В первом скрипте несколько ошибок и дыр.
    1. file и null установлены только если существует директория архива
    2. Mkdir | chmod - зачем тут пайп?
    3. $dir="$HOME/.archive" ... Mkdir $dir - если в $HOME есть пробел или любой другой спецсимвол, то начнутся спецэффекты.
    4. if [ $file == $null ]; если в переданном файле спецсимволы, то получим спецэффекты. Кроме того, условие сработает если нет директории архива.
    5. mv $file $dir$(date "+%H.%d.%m").$file та же ошибка, те же спецэффекты. И ещё одна проблема: если в течение часа мы "удаляем" два файла с одинаковым именем, то бэкап теряется. Проблема становится ещё более интересной в случае директорий.

    Вместо второго скрипта можно использовать which или whereis. (этот и следующий на ошибки не проверял). Фунционал третьего скрипта умеет команда date.

    Ответить
  3. Ну, с нормализацией даты можно и проще, например так: date '+%M:%H %e %B %Y'
    Разукрашивающая последовательность вида ${esc}[что-то_здесь - работает не навсех андроид-девайсах, посему кроссплатформнее использовать \033[что-то_здесь
    В общем-то скрипты для тренировки. А так да, с годами у каждого пользователя Unix-подобных ОС, накапливается порядочное количество скриптов для удобства работы. Я вот, например, всегда забывал, как пересчитывать права файлов в циферки, в rwx и написал тогда это (сейчас уже не использую, т.к. уже запомнилось, что -rwxr-xr-x - это 0755, только из-за редкости использования SUID и SGID ещё путаю):
    #!/bin/bash
    #
    # calcmod
    # Calculation of permission
    # Author: Serega@Russia
    #
    ############

    # Вывод ошибок:
    errorka()
    {
    echo -e "\033[31;1mОшибка аргумента!\033[0m\n"
    exit 0
    }
    #=============#

    # Вывод справки:
    helpik()
    {
    echo -en "\033[1m" 1>&2
    echo -n 'calcmod'
    echo -en "\033[0m" 1>&2
    echo ' [аргумент]'
    echo ' Примеры:'
    echo ' calcmod 755'
    echo ' calcmod 0755'
    echo ' calcmod rwxr--r--'
    echo ' calcmod rwsr--r--'
    echo ' calcmod rwSr--r--'
    echo ' calcmod rwxr--r-T'
    echo ' calcmod rwxr--r-t'
    echo ' calcmod П'
    echo ' calcmod Г'
    echo ''
    exit 0
    }
    #==============#

    # Вывод значений (печать):
    print_letter()
    {
    i=1
    uid=0
    gid=0
    stick=0
    trio_mode=$(echo "$mode" | sed 's/[st]/x/g;s/[ST]/-/g;s/^\(...\)\(...\)\(...\)/\1 \2 \3/')
    for trio in $trio_mode
    do
    if (( $i == 1 ))
    then
    echo -n "User: "
    exp_trio=$(echo "$trio" | sed 's/\(.\)/ \1/g;s/^ //')
    for symb in $exp_trio
    do
    if [ "$symb" != '-' ]
    then
    echo -en "\033[42;31;1m" 1>&2
    echo -n "$symb"
    echo -en "\033[0m" 1>&2
    else echo -n "$symb"
    fi
    done
    echo ''
    elif (( $i == 2 ))
    then
    echo -n "Group: "
    exp_trio=$(echo "$trio" | sed 's/\(.\)/ \1/g;s/^ //')
    for symb in $exp_trio
    do
    if [ "$symb" != '-' ]
    then
    echo -en "\033[42;31;1m" 1>&2
    echo -n "$symb"
    echo -en "\033[0m" 1>&2
    else echo -n "$symb"
    fi
    done
    echo ''
    elif (( $i == 3 ))
    then
    echo -n "Other: "
    exp_trio=$(echo "$trio" | sed 's/\(.\)/ \1/g;s/^ //')
    for symb in $exp_trio
    do
    if [ "$symb" != '-' ]
    then
    echo -en "\033[42;31;1m" 1>&2
    echo -n "$symb"
    echo -en "\033[0m" 1>&2
    else echo -n "$symb"
    fi
    done
    echo ''
    fi
    let i=i+1
    done
    if (( $check_bit == 0 ))
    then
    if [ -z $(echo "$mode" | sed '/^..s/d;/^..S/d') ]
    then
    echo -n 'SUID: '
    echo -en "\033[43;31;1m" 1>&2
    echo -n '+'
    echo -en "\033[0m" 1>&2
    echo ''
    else echo 'SUID: -'
    fi
    if [ -z $(echo "$mode" | sed '/^.....s/d;/^.....S/d') ]
    then
    echo -n 'SGID: '
    echo -en "\033[43;31;1m" 1>&2
    echo -n '+'
    echo -en "\033[0m" 1>&2
    echo ''
    else echo 'SGID: -'
    fi
    if [ -z $(echo "$mode" | sed '/t$/d;/T$/d') ]
    then
    echo -n 'Sticky: '
    echo -en "\033[43;31;1m" 1>&2
    echo -n '+'
    echo -en "\033[0m" 1>&2
    echo ''
    else echo 'Sticky: -'
    fi
    else
    echo -e 'SUID: ?'
    echo -e 'SGID: ?'
    echo -e 'Sticky: ?'
    fi
    }
    #========================#

    # Расчёт из буквенных значений:
    calcmod_letter()
    {
    (( "$len_arg" != 9 )) && errorka
    trio_arg=$(echo "$arg" | sed 's/^\(...\)\(...\)\(...\)/\1 \2 \3/')
    i=1
    bit=0
    rwx=''
    for trio in $trio_arg
    do
    n=0
    exp_trio_arg=$(echo "$trio" | sed 's/\(.\)/ \1/g;s/^ //')
    symb=$(echo "$exp_trio_arg" | cut -d ' ' -f1)
    [ -z $(echo "$symb" | grep '[r-]') ] && errorka
    [ "$symb" = 'r' ] && n=4
    symb=$(echo "$exp_trio_arg" | cut -d ' ' -f2)
    [ -z $(echo "$symb" | grep '[w-]') ] && errorka
    [ "$symb" = 'w' ] && let n=n+2
    symb=$(echo "$exp_trio_arg" | cut -d ' ' -f3)
    [ -z $(echo "$symb" | grep '[xsS-]') ] && (( $i != 3 )) && errorka
    [ -z $(echo "$symb" | grep '[xtT-]') ] && (( $i == 3 )) && errorka
    if [ "$symb" = 'x' ]
    then let n=n+1
    elif [ "$symb" = 's' ]
    then
    let n=n+1
    (( $i == 1 )) && let bit=bit+4
    (( $i == 2 )) && let bit=bit+2
    elif [ "$symb" = 'S' ]
    then
    (( $i == 1 )) && let bit=bit+4
    (( $i == 2 )) && let bit=bit+2
    elif [ "$symb" = 't' ]
    then
    let n=n+1
    let bit=bit+1
    elif [ "$symb" = 'T' ]
    then
    let bit=bit+1
    fi
    let i=i+1
    rwx=$(echo "$rwx$n")
    done
    mode="$arg"
    print_letter
    (( $check_bit != 0 )) && check_calc=1 && bit='?'
    mode="$bit$rwx"
    }
    #=============================#

    # Расчёт из цифровых значений:
    calcmod_numeral()
    {
    # if (echo "$arg" | grep -i '[8,9,a-z]' > /dev/null)
    if (echo "$arg" | grep -i '[^0-7]' > /dev/null)
    then errorka
    fi
    (( "$len_arg" > 4 || "$len_arg" &2
    script_name=$(basename "$0")
    if [[ "$script_name" != 'calcmod' ]]
    then
    echo -en "\033[33;1m" 1>&2
    echo -e "Зачем Вы меня переименовали?\nWhy did they rename me?"
    echo -en "\033[0m" 1>&2
    echo -e "Вам не нравится моё имя calcmod?\nYou do not like my name calcmod?"
    sleep 3
    fi
    [ -n "$2" ] && errorka
    arg="$1"
    check_bit=0
    check_calc=0
    len_arg=$(echo -n "$arg" | wc -m)
    if [ "$arg" = "-?" ]
    then helpik
    elif [ "$arg" = "-h" ]
    then helpik
    elif [ "$arg" = "--help" ]
    then helpik
    elif (echo "$arg" | grep '[0-7]' > /dev/null)
    then calcmod_numeral
    elif (echo "$arg" | grep '[r,w,x,s,S,t,T,-]' > /dev/null)
    then calcmod_letter
    elif [ "$arg" = 'П' ]
    then
    arg='rwxr-xr-x'
    len_arg=9
    check_bit=1
    calcmod_letter
    elif [ "$arg" = 'п' ]
    then
    arg='---rwxr-x'
    len_arg=9
    check_bit=1
    calcmod_letter
    echo -en "\033[33;1m" 1>&2
    echo 'Warning!'
    echo -en "\033[0m" 1>&2
    echo '"П", "п" - разные!'
    elif [ "$arg" = 'Г' ]
    then
    arg='rw-r--r--'
    len_arg=9
    check_bit=1
    calcmod_letter
    elif [ "$arg" = 'г' ]
    then
    arg='---rw-r--'
    len_arg=9
    check_bit=1
    calcmod_letter
    echo -en "\033[33;1m" 1>&2
    echo 'Warning!'
    echo -en "\033[0m" 1>&2
    echo '"Г", "г" - разные!'
    elif [ "$arg" = 'Т' ]
    then
    arg='rwx-w--w-'
    len_arg=9
    check_bit=1
    calcmod_letter
    elif [ "$arg" = 'О' ]
    then
    arg='rwxr-xrwx'
    len_arg=9
    check_bit=1
    calcmod_letter
    elif [ "$arg" = 'L' ]
    then
    arg='r--r--rwx'
    len_arg=9
    check_bit=1
    calcmod_letter
    else errorka
    fi
    #######################

    # Вывод последней строки (печать):
    if (( $check_bit != 0 && $check_calc != 0 ))
    then
    mode=$(echo "$mode" | sed 's/^.//')
    echo -n 'Code: ?'
    echo -en "\033[36;1m" 1>&2
    echo "$mode"
    echo -en "\033[0m" 1>&2
    else
    echo -n 'Code: '
    echo -en "\033[36;1m" 1>&2
    echo "$mode"
    echo -en "\033[0m" 1>&2
    fi
    ##################################

    exit 0

    Ответить
  4. Приветствую Вас. Установил debian10.8-xfce-x64 c офф. сайта.
    В режиме live c флешки команда lsb_release -a работает, а в установленной системе команда не найдена, не понятно, ядро одно и тоже, спасибо

    Ответить

Оставьте комментарий