Bash: различия между версиями

Материал из sysadm
Перейти к навигации Перейти к поиску
Строка 183: Строка 183:
  
 
MyFunc vol1 vol2
 
MyFunc vol1 vol2
 +
</pre>
 +
 +
= запуск фоновых процессов =
 +
<pre>
 +
command &      # запускает процесс и возвращает управление в консоль
 +
                # вывод процесса продолжает идти в консоль
 +
                # закрытие родительского процесса (т.е. консоли) приведет к закрытию процесса
 +
 +
# при обычном запуске любой дочерний процесс привязан к родительскому процессу
 +
# при закрытии родительского процесса происходит HUP (hang up) закрытие всех связанных дочерних процессов
 +
 +
# команда nohup (no hang up) запускает дочерний процесс, отвязывает его от себя и закрывается, дочерний процесс не закрывается
 +
# по умолчанию вывод дочернего процесса направляется в файл nohup.out, который создается в текущем каталоге
 +
 +
nohup command &> /dev/null &      # процесс отвязывается от родительского, вывод направляется в /dev/null, управление возвращается в консоль
 +
                                  # при закрытии консоли, процесс не закрывается
 +
 
</pre>
 
</pre>
  

Версия 11:32, 3 сентября 2025

Обзор

bash - это наиболее популярный но не единственный командный интерпретатор в среде Linux.

Исполняемый файл обычно расположен здесь /bin/bash.

Код скрипта должен начинаться строкой

#!/bin/bash

Варианты запуска скрипта

# текущий командный интерпретатор запустит интерпретатор bash как дочерний процесс, который выполнит скрипт
/bin/bash /home/myuser/myscript.sh

# текущий интерпретатор выполнит скрипт в рамках своего процесса,
# если в строке #! не задан другой тип интерпретатора 
. /home/myuser/myscript.sh

Условия

if <command>
then
  <command>
else
  <command>
fi

# пример, если ошибка, то
# ! - команда отрицания
# [ - команда проверки условия (пробелы важны)
if ! [ $? -eq 0 ]
then
  echo ERROR
fi

# проверка на существование файла
if [ -f /path/to/file ]; then
    echo 'File exists.'
else
    echo 'File does not exist.'
fi

Циклы

for

По списку

for <var> in <list>
do
  команды
done

<list> := если путь к каталогу, то перечисляется содержимое каталога
<list> := если текст, то перечисляются фрагменты текста, разделитель определяется переменной $IFS. По умолчанию, IFS=' '.

# пример перечисления строк файла
IFS=$'\n'
for a in $(cat /etc/password)
do 
  echo $a
done

# пример перечисления массива
myArr[0]='item1'
myArr[1]='item2'
myArr[2]='item3'

for i in "${!myArr[@]}"
do
  echo ${myArr[$i]}
done


В стиле С

for (( i=0; i<10; i++ ))
do
  команды
done

команды управления циклом

# прервать текущую итерацию и перейти к следующей
continue

# прервать цикл
break

Перенаправление вывода


 >  Syntax: file_descriptor >  file_name
 >& Syntax: file_descriptor >& file_descriptor
 &> Syntax: &> file_name

# примеры
 ls > file.txt    # перенаправление stdout в файл
 ls 1 > file.txt  # перенаправление stdout в файл

 ls 2 > file.err  # перенаправление stderr в файл
 ls 2>&1          # перенаправление stderr в stdout

 ls 1 > file.txt 2 > file.txt  # перенаправление stdout и stderr в file.txt, файл будет открыт один раз
 ls &> file.txt                # перенаправление stdout и stderr в file.txt, файл будет открыт один раз

Cкобки (brackets)

Ссылки по теме:

( ... ) - блок команд, выполняется в рамках отдельного дочернего процесса

a=2
(
  a=3
  echo $a
)
echo $a

#вывод будет таким
3
2

{ ... } - блок команд, выполняются в рамках текущего процесса

a=2
{
  a=3
  echo $a
}
echo $a

#вывод будет таким
3
3

<( ... ) - блок команд, вывод которых передается в динамически создаваемую область памяти, при этом сам блок возвращает путь к этой области в виде /dev/fd/63. Также необходимо учитывать, что данные области памяти удаляются сразу после выполнения первого дочернего процесса запущенного скриптом.

echo <(echo test1; echo test2) <(echo test3)

#вывод
/dev/fd/63 /dev/fd/62

cat <(echo test1; echo test2) <(echo test3)

#вывод
test1
test2
test3

Ввод пароля

echo password:
read -s pass
mysql -u root -p $pass

Функции

function MyFunc {
  echo Параметр 1 [$1]
  echo Параметр 2 [$2]
  return 0
}

MyFunc vol1 vol2

запуск фоновых процессов

command &       # запускает процесс и возвращает управление в консоль
                # вывод процесса продолжает идти в консоль
                # закрытие родительского процесса (т.е. консоли) приведет к закрытию процесса

# при обычном запуске любой дочерний процесс привязан к родительскому процессу
# при закрытии родительского процесса происходит HUP (hang up) закрытие всех связанных дочерних процессов

# команда nohup (no hang up) запускает дочерний процесс, отвязывает его от себя и закрывается, дочерний процесс не закрывается
# по умолчанию вывод дочернего процесса направляется в файл nohup.out, который создается в текущем каталоге

nohup command &> /dev/null &       # процесс отвязывается от родительского, вывод направляется в /dev/null, управление возвращается в консоль
                                   # при закрытии консоли, процесс не закрывается

Обработка ошибок

Прерывание

set -e
# некоторый критический блок кода, где ошибка недопустима
# выполнение скрипта прервется, если какая-либо команда вернет не 0
# но это не будет работать для промежуточных команд в серии пайпов
true | false | true
echo "Это будет напечатано"
set +e

set -o pipefail -e
# код будет прерван, даже если ошибка возникла внутри серии пайпов
true | false | true
echo "Это не будет напечатано"
set +e

Ловушки

#!/bin/bash

trap 'echo trap SIGINT' SIGINT
trap 'echo trap SIGTERM' SIGTERM
trap 'echo trap SIGHUP' SIGHUP
trap 'echo trap SIGQUIT' SIGQUIT
trap 'echo trap EXIT' EXIT
trap 'echo trap ERR' ERR

echo 'start'
sleep 1m
echo 'end'

# удаление ловушки
trap - ERR

# ловушка ERR не срабатывает на команде, если используется конструкция
command && echo OK || echo ERROR

# устанавливает наследование trap (DEBUG, RETURN) в функциях и subshell процессах
set -T
# устанавливает наследование trap (ERR) в функциях и subshell процессах
set -E