Skip to main content

Bash скрипты

При запуске скрипта создается дочерняя консоль, в ней выполняется скрипт и результат возвращается в консоль.

Можно запускать через source, имя (если . в PATH), ./... , и ./ ... & С фоновой задачей аккуратно с объемом вывода, ^C не работает.

Функции


function functname
{
shell commands
}

functname ( )
{
shell commands
}

Используют позиционные переменные. 

functname "one" $7

Если внутри функции нужна локальная переменная, то local var1="something", иначе используется глобальная переменная.

Статус возврата из функции перезаписывается после каждого вызова команды, поэтому при необходимости возврата статуса некоторой функции внутри нужно сохранять статус.

cd baddir
echo $?

По умолчанию возвращается статус вызова последней команды. Либо через return N 

builtin mkdir "/var/first"
es=$?
echo "$OLDPWD --> $PWD"
return $es

Желательно возвращать код результата, а не просто цифру.

Программы для работы с функциями

declare -f список функций с описанием

-F только имена функций
unset fname удалить функцию из памяти
type fname Описание функции

-t выведет тип

Приоритет при вызове из консоли

  1. Aliases
  2. Служебные слова типа if, ...
  3. Функции
  4. Встроенные команды типа cd, type, ...
  5. Скрипты и исполняемые команды

Переменные

Описывается $varname или ${varname} Например есть переменная UID. Для вывода 0_ нужно использовать echo ${varname}_

$1, $2, ... Позиционные параметры
$* Строка, содержащая все параметры через пробел
$@ Равна N строкам-параметрам. Актуально при передаче в функции.
$# Количество аргументов
var1=$(cmd) Сохранение результата cmd в переменную

Определение глобальной переменной: var1="something"

Обработка значений переменных перед вводом

${varname:-word } Если переменная не существует или существует но пустая - вернет word
${varname:=word} Если переменная не существует или существует но пустая - присвоит ей word и вернет word
${varname:?message} Если переменная не существует или существует но пустая - выведет сообщение и завершит скрипт
${varname:+word} Если переменная существует или пустая - вернет word, иначе null
${varname:offset:length}

Срез. 

count=frogfootman

${count:4} вернет footman

${count:4:4} вернет foot

Обработка переменных 

${var#pattern}

 


Если шаблон совпадает с началом значения переменной - удалить самую короткую часть от начала строки с совпадением и вернуть результат

var="/home/user/docs/file.txt"
echo ${var#*/}   # home/user/docs/file.txt   (отрезан только первый "/")

${var##pattern}

var="/home/user/docs/file.txt"

echo ${var##*/}  # file.txt                  (отрезано всё до последнего "/")

${variable%pattern}

file="archive.tar.gz"

echo ${file%.*}   # archive.tar

${variable%%pattern}

file="archive.tar.gz"

echo ${file%%.*}  # archive 

${variable/pattern/string}

Наибольшее совпадение шаблона с переменной заменяется строкой. Первое совпадение

${variable//pattern/ string}

Наибольшее совпадение шаблона с переменной заменяется строкой. Все совпадения


 echo -e ${PATH//:/'\n'}

выведет разделенное через : значение в значения списком

Длина значения ${#filename}

Упрасловление потокомя

Условия завершения программы

Вариант 1: Условие анализируется не на логическом, а на статусе результата (exit status) выполнения программы. 0 - ОК, 1-255 ошибка.

if condition
then
statements
[elif condition
then statements...]
[else
statements]
fi

ВарУсловие анализа строк

2:

 конструкция [], внутри нее возможны условия проверки и сравнения строк.

str1 = str2 Строка 1 равна строке 2
str1 != str2 Строка 1 не равна строке 2
str1 > str2 str1 < str2 Больше/меньше
-n str1 Строка 1 не пустая
-z str1 Строка 1 пустая

Условия сравнения чисел

-ltМенее чем
-leМеньше или равно
-eqРавно
-geБольше или равно
-gtБольше
-neНе равно

Можно комбинировать 

if command && [ condition ]; then

Логика внутри условия

&& или -a

Выполнить команду 1, если статус 0 - выполнить команду 2

if statement1 && statement2
then
...
fi
|| или -o

Выполнить команду 1, если статус не 0 - выполнить команду 2

if statement1 || statement2
then
...
fi
!

Отрицание

Свойства файла, проверяемые в условиях




-a file, -e file Файл существует
-d file Директория существует
-f file Файл существует и является файлом (не директория или специальный файл)
-r file, -w file Есть право чтения файла, Есть право записи в файл, 
-x file Есть право исполнения файла или право поиска в директории
-s file Файл существует и не пустой
-N file Файл был изменен с момента последнего чтения
-O file, -G file Запустивший скрипт является владельцем файла, Группа запустившего скрипт входит в группу файла
file1 -nt file2 file1 новее file2 (сравниваются время модификации)
file1 -ot file2 file1 старее file2 (сравниваются время модификации)


Цикл for

Итерируется только по полному списку.

for name [in list] 
    do
    statements that can use $name...
    done

Если list не определен, то используется $@

Есть переменная IFS 

IFS=:
for dir in $PATH
  do
    ls -ld $dir
  done

Цикл while

 

while condition do
statements...
done

Цикл until

 

until command; do
statements...
done

 

Case

for filename in "$@"; do
  pnmfile=${filename%.*}.ppm
  case $filename in
    *.jpg ) exit 0 ;;
    *.tga ) tgatoppm $filename > $pnmfile ;;
    *.xpm ) xpmtoppm $filename > $pnmfile ;;
    *.pcx ) pcxtoppm $filename > $pnmfile ;;
    *.tif ) tifftopnm $filename > $pnmfile ;;
    *.gif ) giftopnm $filename > $pnmfile ;;
    * ) echo "procfile: $filename is an unknown graphics file." 
        exit 1 ;;
  esac
  outfile=${pnmfile%.ppm}.new.jpg
  pnmtojpeg $pnmfile > $outfile
  rm $pnmfile
done