Существует достаточное количество оболочек, например - sh, zsh, ksh и другие. Но мы остановимся на Bash, ведь это самая популярная оболочка среди Linux. Теперь даже Microsoft добавила поддержку Bash.
Эта статья предназначена для тех кто хоть немного знаком с языком сценариев Bash. Давайте рассмотрим некоторые примеры Bash скриптов, которые могут быть полезными в вашей повседневной работе.
Содержание статьи
Примеры Bash скриптов в Linux
Чтобы посмотреть какой интерпретатор команд у вас используется введите команду:
echo $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 вы можете прочитать здесь.
"исползовать" - опечатка, пропущен мягкий знак
Сегодня ничего мы не разобрали...
кроме как узнали что там у нас за интерпретатор а дальше
я просто деранул с нета пару "примеров" но что там я сам не в курсе ребята...
В первом скрипте несколько ошибок и дыр.
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.
круто... зря прочитал
Ну, с нормализацией даты можно и проще, например так: 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
Приветствую Вас. Установил debian10.8-xfce-x64 c офф. сайта.
В режиме live c флешки команда lsb_release -a работает, а в установленной системе команда не найдена, не понятно, ядро одно и тоже, спасибо