Главная >> Информация >> Примеры 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 вы можете прочитать здесь.

Pеклама
Посмотреть детали

Anubis – это максимально легкое open-source решение, созданное специально для защиты небольших веб-ресурсов от бесконечного потока запросов от ботов и AI парсеров. Этот инструмент можно считать "ядерным вариантом", потому что он заставляет ботов выполнять вычисления похожие на майнинг криптовалюты. Но это неплохая альтернатива для тех, кто не может или не хочет использовать Cloudflare. Посмотреть детали

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 работает, а в установленной системе команда не найдена, не понятно, ядро одно и тоже, спасибо

    Ответить

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