В цьому розділі ми обговоримо, яким чином ви можете впливати на середовище вашої оболонки:

  • редагуючи файли ініціалізації оболонки
  • використовуючи змінні
  • використовуючи різні стилі цитування
  • виконуючи арифметичні обчислення
  • присвоюючи псевдоніми
  • використовуючи розширення та заміни

Файли ініціалізації оболонки

Загальносистемні файли ініціалізації

/etc/profile

Якщо оболонка запущена з опцією --login чи як sh, «bash» зчитує інструкції з файлу /etc/profile. Як правило в цей час установлюються змінні PATH, USER, MAIL, HOSTNAME та HISTSIZE. В деяких системах в цьому ж файлі задається значення umask; в інших тут знаходяться вказівники на інші файли, як от

  • /etc/inputrc, загальносистемний файл ініціалізації, в якому ви можете задати стиль дзвінка командного рядка.
  • каталог /etc/profile.d, що містить файли, які задають загальносистемну поведінку певних програм

Всі налаштування, які ви хочете задати для вашого користувацього середовища, повинні знаходитись в цьому файлі. Він може виглядати, наприклад, так:

# /etc/profile
# Загальносистемне середовище та запускні програми, для налаштування реєстрації
PATH=$PATH:/usr/X11R6/bin
# Без файлів помилок (core)
ulimit -S -c 0 > /dev/null 2>&1

USER="`id -un`"
LOGNAME=$USER
MAIL="/var/spool/mail/$USER"

HOSTNAME=`/bin/hostname`
HISTSIZE=1000

# Клавіатура, дзвінок, стиль відображення: зчитати конфігураційний файл:
if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then
   INPUTRC=/etc/inputrc
fi

PS1="\u@\h \W"

export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC PS1

# Джерельні файли ініціалізації для певних програм (ls, vim, less, ...)
for i in /etc/profile.d/*.sh ; do
    if [ -r "$i" ]; then
       . $i
    fi
done

# Налаштування для ініціалізації програм
source /etc/java/java.conf
export NPX_PLUGIN_PATH="$JRE_HOME/plugin/ns4plugin/:/usr/lib/netscape/plugins"
PAGER="/usr/bin/less"
unset i

Цей файл конфігурації встановлює деякі основні змінні середовища оболонки, а також змінні, що необхідні для запуску Java та/чи Java програм у веб-броузері. За докладнішою інформацією зверніться до параграфу 3.2.

Перегляньте розділ 7 для докладнішої довідки про конструкцію if, що використовується в цьому файлі; у розділі 9 обговорюються цикли (конструкція for).

Джерельні коди «bash» містять приклад файлів profile для загального та особистого вжитку. Попередній приклад, та приклад, що подано далі, потребують певних змін для того, щоб можна було їх застосовувати у вашому середовищі!

/etc/bashrc

В системах з багатьма оболонками було б краще задавати специфічні для «bash» зміни в цьому файлі, оскільки /etc/profile зчитується також і іншими оболонками. Помилки, що генерують інші оболонки, зустрічаючи параметри, властиві тільки для «bash» призвели до розділення конфігураційних файлів для різних оболонок. В такому випадку користувацький файл ~/.bashrc мусить вказувати на /etc/bashrc для того, щоб включити його в процес ініціалізації оболонки під час реєстрації.

У вашій системі також файл /etc/profile може містити лише змінні середовища та початкові налаштування програм, тоді як /etc/bashrc міститиме визначення функцій та псевдонімів. В такому випадку на файл /etc/bashrc мусить бути посилання в /etc/profile чи в індивідуальних користувацьких файлах.

Джерельні коди «bash» містять приклади файлів bashrc; окрім того ви можете знайти їх в /usr/share/doc/bash-2.05b/startup-files. Наведена нижче частину файлу bashrc є в документації bash:

alias ll='ls -l'
alias dir='ls -ba'
alias c='clear'
alias ls='ls --color'

alias mroe='more'
alias pdw='pwd'
alias sl='ls --color'

pskill()
{
       local pid

       pid=$(ps -ax | grep $1 | grep -v grep | gawk '{ print $1 }')
       echo -n "killing $1 (process $pid)..."
       kill -9 $pid
       echo "slaughtered."
}

Окрім загальних псевдонімів він також містить зручні псевдоніми, які запустять вірні команди навіть якщо ви помилитесь при їх введенні. Ми будемо розглядати псевдоніми в параграфі 3.5.2. Цей файл також містить функцію pskill; функції ми будемо вивчати в розділі 11.

Особисті користувацькі файли налаштувань

Примітка: У мене немає цих файлів!

Цих файлів може і не бути у вашому домашньому каталозі. Створіть їх, якщо потрібно.

~/.bash_profile

Цей файл має більшу вагу, аніж загальносистемний. В ньому користувач може задавати додаткові налаштування середовища, чи перепризначити системні.

franky~> cat .bash_profile
#################################################################
#                                                               #
#   файл.bash_profile                                           #
#                                                               #
#  Виконується з оболонки bash, коли ви реєструєтесь у системі. #
#                                                               #
#################################################################

source ~/.bashrc
source ~/.bash_login
case "$OS" in
  IRIX)
    stty sane dec
    stty erase
    ;;
#  SunOS)
#    stty erase
#    ;;
  *)
    stty sane
    ;;
esac

Цей користувач встановлює клавішу видалення попереднього символу на різних операційних системах. Окрім цього, зчитуються файли .bashrc та .bash_login.

~/.bash_login

Цей файл містить специфічні команди, які зазвичай виконуються тільки після реєстрації в системі. Наприклад, ми використаємо його, щоб задати значення umask та щоб відтворити список користувачів, що працюють в системі в момент нашої реєстрації. Також користувач отримує календар на поточний місяць.

#######################################################################
#                                                                     #
#   Файл bash_login                                                   #
#                                                                     #
#   Команди, що виконуються з оболонки «bash», коли ви реєструєтесь   #
#   у системі (викликається .bash_profile)                            #
#                                                                     #
#######################################################################
#   захист файлів
umask 002       # Мені можна все, групі та іншим лише читати
#   всячина
w
cal `date +"%m"` `date +"%Y"`

Цей файл буде зчитано у випадку якщо не знайдено ~/.bash_profile.

~/.profile

За відсутності ~/.bash_profile та ~/.bash_login аналізується файл ~/.profile. В ньому можуть знаходитись також установки, що використовуються іншими оболонками. Зауважте, що інші оболонки можуть не зрозуміти синтаксис bash.

~/.bashrc

Сьогодні доволі часто застосовується запуск оболонки без реєстрації, наприклад, якщо ви реєструвались у системі засобами Х. В цьому випадку, запускаючи оболонку, користувач не повинен вводити свого імені та паролю; реєстрації не відбувається. В такому випадку «bash» шукає файл ~/.bashrc, то ж в ньому знаходяться посилання на файли, що аналізуються під час реєстрації, щоб вам не доводилось вводити одні і ті ж команди двічі.

В наведеному файлі після аналізу загальносистемного файлу /etc/bashrc встановлюються кілька псевдонімів та змінних для деяких програм.

franky ~> cat .bashrc
# /home/franky/.bashrc
# Джерело загальних означень
if [ -f /etc/bashrc ]; then
      . /etc/bashrc
fi

# опції оболонки
set -o noclobber

# мої змінні оболонки
export PS1="\[\033[1;44m\]\u \w\[\033[0m\] "
export PATH="$PATH:~/bin:~/scripts"

# мої псевдоніми
alias cdrecord='cdrecord -dev 0,0,0 -speed=8'
alias ss='ssh octarine'
alias ll='ls -la'

# підправити mozilla
MOZILLA_FIVE_HOME=/usr/lib/mozilla
LD_LIBRARY_PATH=/usr/lib/mozilla:/usr/lib/mozilla/plugins
MOZ_DIST_BIN=/usr/lib/mozilla
MOZ_PROGRAM=/usr/lib/mozilla/mozilla-bin
export MOZILLA_FIVE_HOME LD_LIBRARY_PATH MOZ_DIST_BIN MOZ_PROGRAM

# підправити шрифти
alias xt='xterm -bg black -fg white &'

# Налаштування BitchX
export IRCNAME="frnk"

# ВСЕ
franky ~>

Інші приклади ви можете знайти в пакунку Bash. Запам’ятайте, що вони потребують змін для того, щоб правильно працювати у вашому середовищі.

~/.bash_logout

Цей файл містить команди, що повинні виконатись при виході із системи. Даний приклад зручно використовувати для віддалених з’єднань, які очищатимуть екран після свого закриття.

franky ~> cat .bash_logout
#######################################################################
#                                                                     #
#   Файл bash_logout                                                  #
#                                                                     #
#   Команди що виконаються з оболонки «bash» при завершенні роботи    #
#                                                                     #
#######################################################################
clear
franky ~>

Зміна конфігураційних файлів оболонки

Після внесення змін до будь-якого з вище перелічених файлів користувач повинен повторно зареєструватись у системі або запустити вбудовану команду source з параметром імені відповідного файлу для того, щоб зміни вступили в силу.

Мал. 3-1

Більшість сценаріїв оболонки запускаються в окремому середовищі: змінні батьківської оболонки недоступні для дочірньої аж поки вони не будуть експортовані батьківською оболонкою. Включення файлу, що містить команди оболонки – це один з методів змінити ваше середовище та встановити змінні у ньому.

Цей приклад демонструє також використання різних підказок командного рядка для різних користувачів. Якщо у вас зелена підказка, можете не хвилюватись; червона ж є потенційно небезпечною.

Зауважте, що команди source resourcefile та . resourcefile є ідентичними.

Для того, щоб не розгубитись серед всіх цих файлів та контролювати себе під час встановлення різних змінних, використовуйте команду echo як під час наладки сценаріїв (?параграф 2.3.2). Ви можете додати рядки на кшталт цих:

echo "Задається PS1 у .bashrc:"
export PS1="[Якесь значення]"
echo "PS1 встановлено у $PS1"

Змінні

Типи змінних

Як уже було показано вище, всі змінні оболонки пишуться великими літерами. «bash» оперує двома типами змінних:

Глобальні змінні

Глобальні змінні або змінні середовища доступні у всіх оболонках. Ви можете їх проглянути за допомогою команд env чи printenv. Ці програми поставляються у пакунку sh-utils.

Нижче наведено типовий вивід:

ranky ~> printenv
CC=gcc
CDPATH=.:~:/usr/local:/usr:/
CFLAGS=-O2 -fomit-frame-pointer
COLORTERM=gnome-terminal
CXXFLAGS=-O2 -fomit-frame-pointer
DISPLAY=:0
DOMAIN=hq.xalasys.com
EDITOR=vi
FCEDIT=vi
FIGNORE=.o:~
G_BROKEN_FILENAMES=1

==дуже багато покусано===

XKEYSYMDB=/usr/X11R6/lib/X11/XKeysymDB
XMODIFIERS=@im=none
XTERMID=
XWINHOME=/usr/X11R6
X=X11R6
YACC=bison -y

Локальні змінні

Локальні змінні доступні тільки в поточній оболонці. За допомогою вбудованої команди set без параметрів можна отримати список локальних змінних. Вивід буде упорядковано відповідно до поточної локалі та відображено в зручному для подальшого використання форматі.

Нижче наведено файл відмінностей між виводом команд printenv та set після видалення функцій, які також виводяться командою set:

franky ~> diff set.sorted printenv.sorted | grep "<" | awk '{ print $2 }'
BASE=/nethome/franky/.Shell/hq.xalasys.com/octarine.aliases
BASH=/bin/bash
BASH_VERSINFO=([0]="2"
BASH_VERSION='2.05b.0(1)-release'
COLUMNS=80
DIRSTACK=()
DO_FORTUNE=
EUID=504
GROUPS=()
HERE=/home/franky
HISTFILE=/nethome/franky/.bash_history
HOSTTYPE=i686
IFS=$'
LINES=24
MACHTYPE=i686-pc-linux-gnu
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
PIPESTATUS=([0]="0")
PPID=10099
PS4='+
PWD_REAL='pwd
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
THERE=/home/franky
UID=504

Змінні за змістом

На відміну від поділу змінних на локальні та глобальні, ми також можемо поділити їх на категорії в залежності від значень, що містяться в змінних. В такому випадку змінні є чотирьох типів:

  • рядкові змінні
  • цілочисельні змінні
  • постійні змінні
  • масиви

Ці типи ми розглянемо в розділі 10. Зараз ми будемо працювати лише із рядковими та цілочисельними змінними.

Створення змінних

Імена змінних є чутливими до регістру символів, і у них типово використовуються великі букви (верхній регістр). Загальноприйнятою практикою є написання імен локальних змінних малими літерами. Хоча ви можете називати змінні як вам заманеться. В іменах змінних можна використовувати цифри, проте першим символом в імені повинна бути літера:

prompt> export 1number=1
bash: export: `1number=1': not a valid identifier

Для того, щоб задати змінну в оболонці, використовуйте конструкцію

VARNAME="value".

Якщо ви поставите пробіл біля лапок (між знаком '=' та лапками) - це буде помилкою. Хорошою звичкою є виділяння лапками змісту змінних перед присвоєнням: це зменшує імовірність помилки.

Кілька прикладів із великими та малими літерами, цифрами та пропусками:

franky ~> MYVAR1="2"
franky ~>; echo $MYVAR1
2
franky ~> first_name="Franky"
franky ~> echo $first_name
Franky
franky ~> full_name="Franky M. Singh"
franky ~> echo $full_name
Franky M. Singh
franky ~> MYVAR-2="2"
bash: MYVAR-2=2: command not found
franky ~> MYVAR1 ="2"
bash: MYVAR1: command not found
franky ~> MYVAR1= "2"
bash: 2: command not found
franky ~> unset MYVAR1 first_name full_name
franky ~> echo $MYVAR1 $first_name $full_name
<--немає виводу-->
franky ~>

Експортування змінних

Змінні, що були створені в попередньому прикладі, доступні тільки у поточній оболонці. Це – локальні змінні: для дочірнього процесу вони будуть недоступними. Для того, щоб передати змінні в дочірню оболонку, ми повинні експортувати їх за допомогою команди export. Звернення до експортованих змінних відбувається так само як і до змінних середовища. Встановлення та експортування змінної робиться за раз:

export VARNAME="value".

Дочірня оболонка може змінювати значення змінних, які вона успадкувала від батьківської, але ці зміни є актуальними тільки в дочірній оболонці:

franky ~> full_name="Franky M. Singh"
franky ~> bash
franky ~> echo $full_name

franky ~> exit
franky ~> export full_name
franky ~> bash
franky ~> echo $full_name
Franky M. Singh
franky ~> export full_name="Charles the Great"
franky ~> echo $full_name 
Charles the Great
franky ~> exit
franky ~> echo $full_name
Franky M. Singh
franky ~>

Коли ми перший раз пробуємо звернутись до змінної full_name в дочірній оболонці, її там немає (команда echo повертає порожній рядок). Ми покидаємо дочірню оболонку та експортуємо змінну full_name в батьківській. Тепер ця змінна доступна в дочірній оболонці. Ми змінюємо її значення в дочірній оболонці, але в батьківській воно залишається попереднім.

Зарезервовані змінні

Зарезервовані змінні оболонки Борна

Bash використовує зарезервовані змінні так само як і оболонка Борна (sh). В деяких випадках «bash» присвоює типове значення змінній. Нижче наведено список таких змінних:

CDPATH : Розділений двокрапками список каталогів, що використовуються при пошуку вбудованою командою cd.

HOME : Домашній каталог поточного користувача; типове значення для вбудованої команди cd. Це значення використовується також при розширення тильди (~).

IFS : Список символів, що використовуються для розділення полів; використовується, коли оболонка розділяє слова як частину розширення.

MAIL : Якщо в цьому параметрі задано ім’я файлу та не визначена змінна MAILPATH, «bash» інформує користувача про прихід пошти у цей файл.

MAILPATH : Розділений двокрапками список імен файлів, які оболонка періодично перевіряє на наявність нової пошти.

OPTARG : Значення останнього аргументу опцій, що оброблений вбудованою командою getopts.

OPTIND : Індекс останнього аргументу опцій, що оброблений вбудованою командою getopts.

PATH : Розділений двокрапками список каталогів, в котрих оболонка шукає програми.

PS1 : Рядок основної підказки. Типовим значенням є "\s-\v\$".

PS2 : Рядок вторинної підказки. Типовим значенням є ">".

Зарезервовані змінні оболонки bash

Ці змінні встановлюються та використовуються оболонкою bash; інші оболонки їх як правило не використовують.

auto_resume : Ця змінна контролює, як оболонка взаємодіє з користувачем та керує завданнями.

BASH : Повний шлях до файлу, що запустив поточну оболонку.

BASH_ENV : Ця змінна встановлюється тоді, коли «bash» викликається для запуску сценарію, її значення розкривається та використовується як ім’я файлу ініціалізації, який зчитується перед запуском сценарію.

BASH_VERSION : Номер версії поточної копії bash.

BASH_VERSINFO : Масив, доступний тільки для читання, елементи котрого містять інформацію про версію поточної копії оболонки.

COLUMNS : Використовується вбудованою командою select для того, щоб визначити ширину терміналу при виводі списків вибору. Автоматично встановлюється при отриманні сигналу SIGWINCH.

COMP_CWORD : Індекс слова, що містить поточну координату курсора, в масиві ${COMP_WORDS}.

COMP_LINE : Поточна командна стрічка.

COMP_POINT : Індекс поточної позиції курсора відносно початку поточної команди.

COMP_WORDS : Масив, що містить окремі слова поточного командного рядка.

COMPREPLY : Масив, з якого «bash» зчитує можливі закінчення для авто доповнення.

DIRSTACK : Масив, що містить поточний стек каталогів.

EUID : Цифровий ідентифікатор поточного користувача.

FCEDIT : Редактор, що використовується за замовчуванням вбудованою командою fc з ключем -e.

FIGNORE : Розділений двокрапками список суфіксів, що ігноруються при розкриванні імен файлів.

FUNCNAME : Ім’я функції оболонки, що виконується в даний момент.

GLOBIGNORE : Розділений двокрапками список виразів, що визначають імена файлів, котрі ігноруватимуться при розкриванні.

GROUPS : Масив, що містить список груп, членом яких поточний користувач.

histchars : До трьох символів, що контролюють розкривання історії, швидку підстановку та токенізацію.

HISTCMD : Індекс поточної команди в списку історії.

HISTCONTROL : Визначає, чи додається команда до списку історії.

HISTFILE : Визначає ім’я файлу, в котрому зберігається історія команд. За замовчуванням це ~/.bash_history.

HISTFILESIZE : Максимальне число рядків, що зберігаються у файлі історії. За замовчуванням 500.

HISTIGNORE : Розділений двокрапками список виразів, що визначають команди, які не зберігаються у списку історії.

HISTSIZE : Максимальне число команд, що зберігаються у списку історії. За замовчуванням 500.

HOSTFILE : Містить ім’я файлу такого ж формату, що й /etc/hosts, який може бути зчитаний у випадку якщо оболонці потрібно буде автоматично доповнити ім’я комп’ютера.

HOSTNAME : Ім’я поточного комп’ютера.

HOSTTYPE : Стрічка, що описує комп’ютер, на котрому запущений bash.

IGNOREEOF : Визначає реакцію оболонки на одиночний символ EOF, отриманий з стандартного вводу.

INPUTRC : Ім’я файлу ініціалізації Readline; переназначає стандартне /etc/inputrc.

LANG : Використовується для визначення локалі в будь-якій категорії, яка не перепризначена явно змінною, що починається з LC_.

LC_ALL : Ця змінна перепризначає значення LANG та будь-якої змінної, що починається з LC_.

LC_COLLATE : ця змінна визначає порядок порівняння під час впорядкування результатів розкривання імен файлів та визначає поведінку виразів діапазонів, класів еквівалентності та правила порівняння під час розкривання імен файлів та співставлення виразів.

LC_CTYPE : Ця змінна визначає інтерпретацію символів та поведінку класів символів під час розкривання імен файлів та співставлення виразів.

LC_MESSAGES : Ця змінна визначає локаль, що використовується для перекладу рядків, котрі оточені подвійними лапками та починаються з символу "$".

LC_NUMERIC : Ця змінна визначає категорію локалі, що використовується для форматування чисел.

LINENO : Номер рядки в поточному сценарію, чи функції.

LINES : Використовується вбудованою командою select щоб визначити довжину рядка для виводу списків вибору.

MACHTYPE : Рядок, що повністю описує тип системи, на котрій запущено bash, в стандартному форматі GNU CPU-COMPANY-SYSTEM.

MAILCHECK : Як за часто (в секундах) оболонка має перевіряти пошту в файлах, які визначаються змінними MAILPATH чи MAIL.

OLDPWD : Попередній каталог, визначений вбудованою командою cd.

OPTERR : Якщо встановлено в 1, «bash» показує помилки, що генеруються вбудованою командою getopts.

OSTYPE : Рядок, що описує операційну систему, на якій запущена bash.

PIPESTATUS : Масив, що містить коди завершення фонових процесів в каналі по мірі старіння; може складатись з єдиного елементу.

POSIXLY_CORRECT : Якщо в середовищі є ця змінна під час запуску bash, значить оболонка запущена в режимі сумісності з posix.

PPID : Ідентифікатор процесу, що запустив bash.

PROMPT_COMMAND : Якщо встановлена, то її значення інтерпретується як команда, яку потрібно виконати перед кожним виводом основної підказки (PS1).

PS3 : Значення цієї змінної використовується як підказка для команди select; за замовчуванням це "#?"

PS4 : Це значення виводиться щоразу перед командою, якщо встановлений ключ -x; стандартно це «+».

PWD : Поточний каталог, що встановлений вбудованою командою cd.

RANDOM : Щоразу при зверненні до цієї змінної генерується випадкове число у інтервалі від 1 до 32767; присвоєння значення цій змінній запускає генератор випадкових чисел.

REPLY : Стандартне значення для вбудованої команди read.

SECONDS : В цій змінній міситься число секунд, що минуло після запуску оболонки.

SHELLOPTS : Розділений двокрапками список ввімкнених ключів оболонки.

SHLVL : Збільшується на 1 щоразу коли запускається ще одна копія bash.

TIMEFORMAT : Значення цієї змінної використовується для визначення форматування часової інформації в каналах, що починаються з вбудованої команди time.

TMOUT : Якщо встановлено значення більше за 0, розглядається як стандартний час очікування для вбудованої команди read. В інтерактивній оболонці інтерпретується як число секунд очікування на ввід команди після виводу основної підказки. «bash» закінчує свою роботу, якщо за цей час не було нічого введено.

UID : Справжнє значення ідентифікатора поточного користувача.

Особливі параметри

Оболонка по-особливому обробляє декілька параметрів. Їх значення можна тільки зчитувати; переприсвоювати їх не можна.

Особливі параметри bash:

$* : Розкриває позиційні параметри, починаючи з поточного. Якщо розкривання відбувається всередині подвійних дужок, параметри розкриваються в одне слово, де значення кожного з параметрів розділені першим символом змінної IFS.

$@ : Розкриває позиційні параметри, починаючи з поточного. Якщо розкривання відбувається всередині подвійних дужок, параметри розкриваються в різні слова.

$# : Розкривається в число позиційних параметрів в десятковій системі числення.

$? : Розкривається в стан виходу останнього виконаного в фоні конвеєра.

$- : Дефіс розкривається в прапорці, визначені під час запуску, вбудованою командою set, або ті, що встановлені оболонкою самостійно (як, наприклад, -i)

$$ : Розкривається в поточний ідентифікатор процесу оболонки.

$! : Розкривається в ідентифікатор процесу останньої виконуваної у фоні (асинхронної) команди.

$0 : Розкривається в ім'я оболонки чи сценарію оболонки.

$_ : Символ підкреслення встановлюється при запуску оболонки і означає повне ім'я оболонки чи виконуваного сценарію. Згодом він розкривається в останній аргумент попередньої команди після її розкриття. Він також розкривається в повне ім'я поточної виконуваної команди. Під час перевірки електронної пошти він позначає ім'я поштової скриньки.

Позиційні параметри – це слова, що йдуть слідом за іменем сценарію оболонки. Вони поміщаються в змінні $1, $2, $3 і так далі аж допоки потрібно. $# містить загальне число параметрів, як це показано в нижченаведеному сценарію:

#!/bin/bash

# positional.sh
# Цей сценарій зчитує три позиційні параметри та роздруковує їх

POSPAR1="$1"
POSPAR2="$2"
POSPAR3="$3"

echo "$1 є першим позиційним параметром, \$1."
echo "$2 є другим позиційним параметром, \$2."
echo "$3 є третім позиційним параметром, \$3."
echo
echo "Всього позиційних параметрів: $#."

Під час виконання сценарію можна передати довільне число параметрів:

franky ~> positional.sh one two three four five
one є першим позиційним параметром, $1.
two є другим позиційним параметром, $2.
three є третім позиційним параметром, $3.

Всього позиційних параметрів: 5.

franky ~> positional.sh one two
one є першим позиційним параметром, $1.
two є другим позиційним параметром, $2.
  є третім позиційним параметром, $3.

Всього позиційних параметрів: 2.

Більше про використання цих параметрів можна прочитати в розділі 7 та параграфі 9.7. Ще кілька прикладів використання особливих параметрів:

franky ~> grep dictionary /usr/share/dict/words
dictionary

franky ~> echo $_
/usr/share/dict/words

franky ~> echo $$
10662

franky ~> mozilla &
[1] 11064

franky ~> echo $!
11064

franky ~> echo $0
bash

franky ~> ls doesnotexist
ls: doesnotexist: No such file or directory

franky ~> echo $?
0

franky ~> echo $?
1

franky ~>

Користувач franky ввів команду, результат якої записався у змінну $_. Ідентифікатор його оболонки – 10662. Після запуску команди у фоні $! містить ідентифікатор фонової задачі. Після завершеної з помилкою програми $? містить значення відмінне від нуля.

Сценарії, що оперують змінними

Окрім того, що змінні роблять сценарій зручнішим для читання, вони дозволяють швидше змінити його для іншого середовища чи для виконання іншої задачі. Зверніть увагу на наступний сценарій, що робить резервну копію домашнього каталогу franky на віддалений сервер:

#!/bin/bash

# Цей сценарій резервує мій домашній каталог

cd /home

# Тут створюється архів
tar cf /var/tmp/home_franky.tar franky > /dev/null 2>&1

# Спершу видалимо старий файл bzip2. пере Направимо помилки, які можуть виникнути
# якщо архів не існує. Потім створимо новий стиснутий файл
rm /var/tmp/home_franky.tar.bz2 2> /dev/null
bzip2 /var/tmp/home_franky.tar

# Скопіюємо файл на інший хост – у нас є ключі ssh щоб робити цю роботу без зайвих
# перепитувань
scp /var/tmp/home_franky.tar.bz2 bordeaux:/opt/backup/franky > /dev/null 2>&1

# Створити часову помітку у файлі протоколу.
date > /home/franky/log/home_backup.log
echo backup succeeded > /home/franky/log/home_backup.log

Перш за все, ви маєте чималий шанс допуститись помилки щоразу вручну набираючи імена файлів та каталогів. По-друге, уявіть собі, що franky дав свій сценарій carol. Вона повинна зробити певні зміни у файлі щоб пристосувати його для своїх потреб. Те ж саме стосується franky, якщо він захоче робити резервні копії якихось інших каталогів. Для полегшення роботи зробіть назви файлів, каталогів, користувачів, серверів та ін. змінними. Після цього вам потрібно буде змінити необхідне значення тільки в одному місці замість шукати й змінювати його по всьому сценарію.

#!/bin/bash

# Цей сценарій резервує мій домашній каталог

# Змініть значення змінних щоб підлаштувати його під себе:
BACKUPDIR=/home
BACKUPFILES=franky
TARFILE=/var/tmp/home_franky.tar
BZIPFILE=/var/tmp/home_franky.tar.bz2
SERVER=bordeaux
REMOTEDIR=/opt/backup/franky
LOGFILE=/home/franky/log/home_backup.log

cd $BACKUPDIR

# Тут створюється архів
tar cf $TARFILE $BACKUPFILES > /dev/null 2>&1

# Спершу видалимо старий файл bzip2. Перенаправимо помилки, які можуть виникнути
# якщо архів не існує. Потім створимо новий стиснутий файл
rm $BZIPFILE 2> /dev/null
bzip2 $TARFILE

# Скопіюємо файл на інший хост – у нас є ключі ssh щоб робити цю роботу без зайвих
# перепитувань
scp $BZIPFILE $SERVER:$REMOTEDIR > /dev/null 2>&1

# Створити часову помітку у файлі протоколу.
date > $LOGFILE
echo backup succeeded > $LOGFILE

Примітка: Великі каталоги та низька пропускна здатність каналу.

Вище наведено простий приклад для кращого розуміння; з малим каталогом та комп’ютерами у одній підмережі. В залежності від розміру каталогу, пропускної здатності каналу та місцезнаходження віддаленого сервера такий сценарій може виконуватись дуже довго щоб застосовувати його для резервування даних. Для таких випадків використовуйте ?rsync щоб отримати однакові каталоги на різних комп’ютерах.

Символи екранування

Навіщо?

Значна кількість клавіш має те чи інше значення в залежності від контексту. Екранування використовується для усунення спеціального значення слів чи символів: лапки можуть відмінити особливе значення спеціальних символів, вони можуть попередити розкривання зарезервованих слів та параметрів.

Символи екранування

Символи екранування (escape characters) використовуються для того, щоб відмінити особливе значення одиночних символів. Зворотна похила риска, не взята у лапки, використовується як спеціальний символ у bash. Вона зберігає буквальне значення наступного символу за винятком символу нового рядка. Якщо після зворотної похилої риски йде символ нового рядка, то він позначає продовження рядка, якщо той довший за ширину терміналу; сама зворотна похила риска видаляється з вхідного потоку та ігнорується.

franky ~> date=20021226

franky ~> echo $date
20021226

franky ~> echo \$date
$date

В цьому прикладі новоствореній змінній date присвоюється певне значення. Перша команда echo відображає значення змінної, але в другому випадку символ долара зберігається.

Одинарні лапки

Одинарні лапки використовується щоб зберегти літеральне значення кожного символу, що знаходиться між ними. Одинарні лапки не можуть знаходитись між іншими одинарними лапками, хіба лише після символу зворотної похилої риски. Продовжуючи попередній приклад:

franky ~> echo '$date'
$date

Подвійні лапки

Використання подвійних лапок зберігає літеральні значення символів, що знаходяться між ними за винятком символів долара, зворотних одинарних лапок та зворотної косої риски.

Символ долара та зворотні одинарні лапки мають спеціальне значення всередині подвійних лапок.

Символ зворотної косої зберігає своє значення лише після символів долара, зворотних лапок, подвійних лапок, ще однієї зворотної косої чи символу нового рядка. Всередині подвійних лапок зворотна коса видаляється з вхідного потоку, коли вона слідує за одним з цих символів. Символи, що передують зворотнім косим та не мають спеціального значення залишаються незміненими для подальшої обробки інтерпретатором.

Подвійні лапки можуть бути вжиті всередині подвійних лапок якщо перед ними буде символ зворотної косої риски.

franky ~> echo "$date"
20021226

franky ~> echo "`date`"
Sun Apr 20 11:22:06 CEST 2003

franky ~> echo "Я сказав: \"Ходи сюди!\""
Я сказав: "Ходи сюди!"

franky ~> echo "\"
More input>"

franky ~> echo "\\"
\

Екранування в стилі ANSI-C

Слова у формі "$'STRING'" розглядаються особливим чином. Слова розкриваються в ланцюжок символів, перед кожним з котрих знаходиться символ зворотної косої, а потім розкриваються згідно стандарту ANSI-C. Список значень спеціальних символів, що екрановані символом зворотної косої, можна знайти в документації до bash.

Локалі

Слова, взяті у подвійні лапки, перед котрими знаходиться символ долара, будуть перекладені відповідно до поточної локалі. Якщо поточною локаллю є С чи POSIX, символ долара ігнорується. Якщо рядок перекладено та замінено, переклад береться у подвійні лапки.

Розкривання оболонки

Загальне

Після того, як команда була розділена на лексеми (див параграф 1.4.1.1), ці лексеми або слова розкриваються чи обраховуються. Існує вісім різновидів виконуваних обрахунків, які будуть обговорюватися в наступних параграфах в тому порядку, в якому вони обраховуються. Після закінчення всіх обрахунків лапки видаляються.

Розкривання фігурних дужок

Розкривання фігурних дужок – це механізм, за допомогою якого можуть генеруватися довільні стрічки. Вирази, що повинні бути згенеровані, приймають форму необов’язкової преамбули, після котрої йде список розділених комами рядків, після котрого йде необов’язковий постскрипт. Преамбула додається до початку кожного рядка, що знаходиться в дужках, а постскрипт – до кінця; розкривання відбувається зліва направо.

Фігурні дужки можуть бути вкладеними; результат розкривання не сортується, натомість віддається перевага порядкові зліва направо:

franky ~> echo sp{el,il,al}l
spell spill spall

Розкривання фігурних дужок виконується перед будь-яким іншим розкриванням і в результаті зберігаються будь-які символи, що мають особливе значення в інших розкриваннях. Це розкривання є строго текстовим. «bash» не застосовує ніякої синтаксичної інтерпретації до контексту розкривання чи до рядків в фігурних дужках. Задля уникнення конфліктів з розкриванням параметрів послідовність "${" не допускається до розкривання.

Правильно сформований вираз для розкривання мусить містити неекрановані ліву та праву фігурні дужки та хоча б одну неекрановану кому. Будь-який невірно сформований вираз залишається без змін.

Розкривання тильди

Якщо слово розпочинається з неекранованого символу тильди ("~"), всі символи аж до першого неекранованого символу похилої риски (або всі символи, якщо похилої риски немає) розглядаються як префікс тильди. Якщо жоден з символів в префіксі не є екранованими, вони трактуються як можливе ім’я користувача. Якщо це ім’я є порожнім рядком, тильда заміняється значенням змінної оболонки HOME. Якщо змінна HOME не встановлена, підставляється домашній каталог поточного користувача. В іншому випадку префікс тильди замінюється домашнім каталогом заданого користувача.

Якщо префіксом тильди є "~+", він замінюється змінною оболонки PWD. Якщо префікс тильди є "~-", то він замінюється на значення змінної OLDPWD, якщо остання встановлена. Якщо символи після тильди є числом, можливо з префіксом "+" чи "-", префікс тильди замінюється відповідним елементом стеку каталогів, як би він був відтворений вбудованою командою dirs, викликаною з символами після тильди як аргументами. Якщо це число вжито без символів "+" чи "-", то вважається, що потрібно застосувати "+".

Якщо ім’я користувача є невірним, або розкривання тильди завершилось невдачею, вираз залишається незмінним.

Кожне присвоєння змінних перевіряється на неекранований префікс тильди відразу після символів ":" чи "=". В цьому випадку також виконується розкривання тильди. Тому можна ви користувати імена файлів з тильдою при присвоєнні значень змінним PATH, MAILPATH чи CDPATH. Наприклад:

franky ~> export PATH="$PATH:~/testdir"

~/testdir буде розкрито в $HOME/testdir, отож якщо $HOME містить /var/home/franky, то каталог /var/home/franky/testdir буде додано до вмісту змінної PATH.

Розкривання параметрів та змінних оболонки

Символ долара означає, що далі йде розкривання параметрів, підстановка команди або арифметичний вираз. Назва параметра чи символ, що має бути розкритий, можуть бути взяті у фігурні дужки, що є необов’язковими, але захищають змінну від випадкового розкривання окремих символів.

Коли застосовуються фігурні дужки, вираз закриває перша фігурна дужка, не екранована символом косої риски чи лапками, а також якщо вона не є частиною вбудованого арифметичного виразу, підстановочної команди чи параметру.

Основною формою параметрів, що будуть розкриватися, є "${PARAMETER}". Підставляється значення змінної PARAMETER. Якщо змінна PARAMETER є позиційним параметром з більш аніж однією цифрою або якщо вона слідує за символом, що не має бути розцінений як частина назви змінної, то фігурні дужки є обов’язковими.

Якщо перший символ у назві PARAMETER є знаком оклику, «bash» використовує дане значення змінної, як ім’я іншої змінної; ця змінна розкривається і саме її значення використовується в подальшій обробці. Такий підхід називають непряме розкривання.

Ви вже знайомі з прямим розкриванням, оскільки воно застосовується весь час, навіть у найпростіших прикладах, як ось наступний:

franky ~> echo $SHELL
/bin/bash

А ось це – приклад непрямого розкривання:

franky ~> echo ${!N*}
NNTPPORT NNTPSERVER NPX_PLUGIN_PATH

Зауважте, що це не те ж саме, що й echo $N*.

Наступна конструкція створює іменовану змінну, якщо вона не існувала до того:

${VAR:=value}

Наприклад:

franky ~> echo $FRANKY

franky ~> echo ${FRANKY:=Franky}
Franky

Особливі параметри, серед яких і позиційні, звичайно, не можуть бути викликані таким чином. В десятому розділі ми обговоримо використання фігурних дужок для обробки змінних. Додаткову інформацію також можна знайти в сторінках довідки bash.

Підстановка команд

Підстановка команд дозволяє замінити команду її виводом. Підстановка команд відбувається тоді, коли команда вживається таким чином

$(command)

або ось так

`command`

Bash виконує підстановку викликом команди command та заміною імені команди її стандартним виводом, з котрого попередньо видаляються всі кінцеві символи нового рядка. Вбудовані символи нового рядка не видаляються, але вони можуть бути видалені під час поділу на слова.

franky ~> echo `date`
Thu Feb 6 10:06:20 CET 2003

Якщо використовується стара форма заміни команд (з використанням зворотних лапок), то символ зворотної похилої зберігає своє буквальне значення за винятком тих випадків, коли він йде після символів долара, зворотних лапок чи ще одного символу зворотної похилої риски. Перший неекранований символ зворотних лапок завершує команду. Якщо використовується форма $(command), всі символи, що знаходяться в дужках вважаються частиною команди, жоден з них не має спеціального значення.

Підстановка команд може бути вкладеною. Щоб використати вкладення, якщо ви використовуєте стару форму заміни команд, заекрануйте внутрішні зворотні лапки зворотними похилими.

Якщо підстановка команд вживається всередині подвійних лапок, поділ слів та розкривання імен файлів не застосовуються до результатів виконання команди.

Арифметичні розкривання

Арифметичні розкривання дозволяють розраховувати арифметичні вирази та підкладати результат на місце виразу. Вони мають такий формат:

$(( EXPRESSION ))

Вираз трактується так, ніби він знаходиться між подвійними лапками; але подвійні лапки всередині круглих дужок ніяким особливим чином не інтерпретуються. Всі лексеми у виразі піддаються розкриванню параметрів, підстановці команд та видаленню лапок. Арифметичні вирази можуть бути вкладеними.

Розрахунок арифметичних виразів проводиться з цілими числами фіксованої ширини без перевірки на переповнення за винятком ділення на нуль, яке відловлюється та розпізнається як помилка. Оператори використовуються ті ж самі, що й в мові С. В порядку спадання пріоритетів їх список виглядає таким чином:

Змінні оболонки дозволені у якості операндів; розкривання параметрів відбувається до обчислення виразу. Всередині виразу до змінних оболонки можна звертатися по імені опускаючи синтаксис розкривання параметрів. Якщо на змінну посилаються, її значення розцінюється як арифметичний вираз. Змінна оболонки не потребує вмикання її числового атрибуту перед використанням.

VAR++ та VAR-- : постінкремент та постдекремент змінної

++VAR та --VAR : преінкремент та предекремент змінної

  • та - : одинарний плюс та мінус

! та ~
: логічне та порозрядне НЕ

** : піднесення до степеня

*, / та % : множення, ділення та ділення націло

  • та - : додавання, віднімання

<< та >> : лівий та правий порозрядний зсув

<=, >=, < і > : оператори порівняння

== і !== : ідентичність та не ідентичність

& : порозрядне І

^ : порозрядне виключаюче АБО

| : порозрядне АБО

&& : логічне І

|| : логічне АБО

вираз ? вираз : вираз : умовна оцінка

=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^= та |= : присвоєння

, : розділювач між виразами

Константи з переднім нулем інтерпретуються як вісімкові числа. Передні "0x" або "0X" позначають шістнадцяткові числа. В інших випадках числа представлені у формі "[ОСНОВА'#']N", де ОСНОВА – ціле число від 2 до 64, що представляє собою основу числення, а N – номер у цій системі числення. Якщо ОСНОВА'#' пропущена, вона приймається рівною 10. Числа більші за 9 представляються малими латинськими літерами, великими латинськими літерами, символами "@" та "_" в такому порядку. Якщо ОСНОВА не перевищує 36, різниці між великими та малими літерами немає.

Оператори розраховуються в порядку пріоритету. Вирази в дужках розраховуються в першу чергу. Якщо можливо, «bash» старається використовувати синтаксис з квадратними дужками:

$[ EXPRESSION ]

Проте в цьому випадку буде лише вирахувано результат виразу, без перевірки. Наприклад:

franky ~> echo $[365*24]
8760

Перегляньте перш за все параграф 7.1.2.2 щоб отримати практичні приклади для сценаріїв.

Підстановка процесів

Підстановка процесів реалізована тільки на системах, які підтримують іменовані канали (FIFO) чи /dev/fd метод іменування відкритих файлів. Вона приймає форму

<(СПИСОК)

чи

>(СПИСОК)

Процес СПИСОК запускається таким чином, що його ввід чи вивід приєднується до FIFO або до якогось файлу у /dev/fd. Ім’я цього файлу передається аргументом поточній команді як результат розкривання. Якщо вжито форму ">(СПИСОК)", запис у файл буде забезпечувати ввід процесу; якщо форму "<(СПИСОК)" – вивід. Зауважте що між символами більше чи менше та дужками не має бути пробілу, щоб дана конструкція не інтерпретувалась як перенаправлення.

Якщо це можливо, підстановка процесу здійснюється одночасно з розкриванням параметрів та змінних, підстановкою команд та обчисленням виразів. Додаткову інформацію можна знайти у параграфі 8.2.3.

Розділення слів

Оболонка переглядає результати розкривання параметрів, підстановки команд та обчислення виразів, які не знаходяться всередині подвійних лапок, задля розділення слів.

Вона трактує кожен символ списку $IFS як розділювач та розділяє результати інших розкривань на слова по цих символах. Якщо IF не визначено, або його значенням є стандартне "<space><tab><newline>" (<пробіл><табуляція><новий рядок>), тоді будь-яка послідовність символів IFS служить розділювачем для слів. Якщо IFS містить значення, що відрізняється від стандартного, тоді послідовність символів „пробіл” та „табуляція” на початку та в кінці кожного слова ігнорується аж поки символ пробілу не появиться в значенні IFS. Будь-який символ в IFS, що не є пробілом разом з будь-яким суміжним символом відмежовує поле. Послідовність пробілів також розглядається як відділювач. Якщо в IFS є порожнє значення, розділення слів не відбувається.

Явні недійсні аргументи (\"\"\"\" чи \"\'\'\") зберігаються. Незалапковані неявні дійсні аргументи, що є результатом розкривання параметрів без значень, видаляються. Якщо параметр без значення розкривається всередині подвійних лапок, результуюче порожнє значення зберігається.

Примітка: Розкривання та розділення слів.

Якщо не відбувається ніякого розкривання, то не відбувається й розділення слів.

Розкривання імен файлів

Після розділення слів якщо не встановлено опцію -f (див параграф 2.3.2), «bash» переглядає кожне слово на наявність символів *, ? та [. Якщо знайдено один з цих символів, слово розглядається як зразок (шаблон) та заміняється відсортованим за абеткою списком імен файлів, що відповідають зразкові. Якщо таких файлів не знайдено і опція оболонки nullglob вимкнена, слово залишається незмінним. Якщо опція nullglob ввімкнена, слово видаляється. Якщо змінна оболонки nocaseglob ввімкнена, пошук імен файлів йде без врахування різниці регістрів.

Якщо зразок використовується для генерування імен файлів, символ крапки на початку імені файлу або відразу за символом косої риски повинен явно співпадати, аж поки залишається ввімкненою опція dotglob. Під час перевірки на відповідність імені файлу символ похилої риски повинен явно співпадати. В інших випадках символ крапки не несе спеціального навантаження.

Змінна оболонки GLOBIGNORE може застосовуватись щоб обмежити набір назв файлів, що відповідають зразкові. Якщо вона встановлена, кожна назва файлу, що відповідає зразкові, видаляється із списку відповідностей, якщо вона відповідає будь-якому із зразків GLOBIGNORE. Назви файлів "." та ".." ігноруються завжди. Проте встановлення GLOBIGNORE дає також ефект ввімкнення опції оболонки dotglob, то ж всі інші назви файлів, що починаються з крапки, вважатимуться такими, що пройшли відповідність. Для того, щоб отримати стару поведінку, коли файли з крапками на початку ігнорувалися, додайте зразок ".*" до списку зразків GLOBIGNORE. Опція dotglob вимикається, якщо GLOBIGNORE не встановлена.

Псевдоніми

Що таке псевдоніми

Псевдоніми дають можливість замінити слово іншим рядком, якщо це слово є першим у простій команді. Оболонка підтримує список псевдонімів, що можуть бути задані чи усунуті за допомогою вбудованих команд alias та unalias. Запуск команди alias” без опцій відобразить список псевдонімів, що відомі поточній оболонці:

franky: ~> alias
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias PAGER='less -r'
alias Txterm='export TERM=xterm'
alias XARGS='xargs -r'
alias cdrecord='cdrecord -dev 0,0,0 -speed=8'
alias e='vi'
alias egrep='grep -E'
alias ewformat='fdformat -n /dev/fd0u1743; ewfsck'
alias fgrep='grep -F'
alias ftp='ncftp -d15'
alias h='history 10'
alias fformat='fdformat /dev/fd0H1440'
alias j='jobs -l'
alias ksane='setterm -reset'
alias ls='ls -F --color=auto'
alias m='less'
alias md='mkdir'
alias od='od -Ax -ta -txC'
alias p='pstree -p'
alias ping='ping -vc1'
alias sb='ssh blubber'
alias sl='ls'
alias ss='ssh octarine'
alias sss='ssh -C server1.us.xalasys.com'
alias sssu='ssh -C -l root server1.us.xalasys.com'
alias tar='gtar'
alias tmp='cd /tmp'
alias unaliasall='unalias -a'
alias vi='eval `resize`;vi'
alias vt100='export TERM=vt100'
alias which='type'
alias xt='xterm -bg black -fg white &'

franky ~>

Псевдоніми корисні для визначення стандартної версії команди, що існує у кількох іпостасях у вашій системі, або для визначення стандартних опцій для команди. Іншим прикладом застосування псевдонімів є виправлення помилок при наборі команд.

Перше слово кожної простої команди, якщо воно не залапковане, перевіряється на те, чи не є воно псевдонімом. Якщо так, воно заміняється своїм відповідником. Назва псевдоніму та текст для заміни можуть містити будь-який правильний ввід оболонки, в тому числі метасимволи оболонки; винятком є символ рівності ("="), що не може з’являтись в імені псевдоніму. Заміна псевдоніму відбувається лише один раз; тобто замінивши ls на ls -F, оболонка не буде рекурсивно шукати псевдоніми у заміненому тексті. Якщо останнім символом у значенні псевдоніму є пробіл або табулятор, тоді наступне слово простої команди також перевіряється на можливість розширення псевдоніму.

Створення та видалення псевдонімів

Псевдоніми створюються вбудованою командою alias. Для постійного використання введіть команду alias в один з файлів ініціалізації вашої оболонки; якщо ви просто введете псевдонім у командному рядку, він буде задіяний тільки у поточному сеансі.

franky ~> alias dh='df -h'

franky ~> dh
Filesystem            Size  Used Avail Use% Mounted on
/dev/hda7             1.3G  272M 1018M  22% /
/dev/hda1             121M  9.4M  105M   9% /boot
/dev/hda2              13G  8.7G  3.7G  70% /home
/dev/hda3              13G  5.3G  7.1G  43% /opt
none                  243M     0  243M   0% /dev/shm
/dev/hda6             3.9G  3.2G  572M  85% /usr
/dev/hda5             5.2G  4.3G  725M  86% /var

franky ~> unalias dh

franky ~> dh
bash: dh: command not found

franky ~>

Bash завжди зчитує як мінімум один повний рядок вводу перш ніж виконати будь-яку з команд в рядку. Псевдоніми розкриваються під час зчитування команди, а не під час її виконання. Тому визначення псевдоніму разом з запуском іншої команди не спричинить потрібного ефекту аж поки не буде зчитаний інший рядок вводу. На команди, що йдуть в одному рядку слідом за визначенням псевдоніму новий псевдонім не діє. Це ж саме відбувається при застосування псевдонімів всередині функцій. Вони розкриваються під час визначення функції, а не під час її виконання, оскільки визначення функції саме по собі є командою. Як наслідок, псевдоніми, визначені під час функції, недоступні після її завершення. Тому краще завжди використовуйте команду alias в окремому рядку; не робіть її частиною складеної команди.

Псевдоніми не успадковуються дочірнім процесом. Оболонка sh не розуміє псевдонімів. Функції детальніше розглядаються в розділі 11.

Підказка: Функції є швидшими.

Псевдоніми проглядаються після функцій, тому їх аналіз займає більше часу. І хоча псевдоніми є легшими для засвоєння, вживання функцій оправдовує себе практично в усіх випадках.

Додаткові опції Bash

Відображення опцій

Ми вже обговорили кілька опцій bash, що вживаються для наладки ваших сценаріїв. В цьому параграфі ми детальніше розглянемо опції bash.

Використовуйте опцію –o вбудованої команди set щоб відобразити всі опції bash:

willy:~> set -o
allexport       off
braceexpand     on
emacs           on
errexit         off
hashall     on
histexpand      on
history     on
ignoreeof       off
interactive-comments    on
keyword     off
monitor     on
noclobber       off
noexec          off
noglob          off
nolog           off
notify          off
nounset     off
onecmd          off
physical        off
posix           off
privileged      off
verbose     off
vi          off
xtrace          off

Зверніться до сторінок документації info, параграф „Вбудовані команди оболонки” -> „Команда set” щоб детальніше дізнатись про кожну опцію. Багато опцій мають односимвольні скорочення: xtrace, до прикладу еквівалентна set -x.

Зміна опцій

Опції оболонки можна змінити під час запуску оболонки чи в процесі її роботи. Вони також можуть бути включені в конфігураційні файли bash.

Наступна команда виконає сценарій у POSIX-сумісному режимі:

willy:~/scripts> bash --posix script.sh

Для тимчасової зміни середовища або для використання у сценаріях є сенс вживати команду set. Використовуйте - (дефіс) для відміни (вимкнення), + для ввімкнення:

willy:~/test> set -o noclobber

willy:~/test> touch test

willy:~/test> date > test
bash: test: cannot overwrite existing file

willy:~/test> set +o noclobber

willy:~/test> date > test

Вищенаведений приклад демонструє опцію noclobber, яка захищає існуючі файли від перезапису з допомогою операцій перенаправлення. Те ж саме відбувається з односимвольними опціями, до прикладу -u, яка розглядатиме звернення до невстановлених змінні як помилку та виходитиме з неінтерактивних оболонок:

willy:~> echo $VAR

willy:~> set -u

willy:~> echo $VAR
bash: VAR: unbound variable

Ця опція зручна для виявлення невірного присвоєння змінним: така ж помилка виникатиме, наприклад, при спробі присвоїти символьне значення змінній, яка повинна містити тільки цілі числа. Ще один, останній, приклад, що демонструє опцію noglob, захищає деякі спеціальні символи від розкривання:

willy:~/testdir> set -o noglob

willy:~/testdir> touch *

willy:~/testdir> ls -l *
-rw-rw-r--    1 willy    willy      0 Feb 27 13:37 *

Підсумок

Середовище «bash» може бути сконфігуроване як глобально так і окремо для кожного користувача. Різноманітні конфігураційні файли використовуються для налаштування поведінки оболонки.

Ці файли містять опції оболонки, установки змінних, визначення функцій та інші складники для створення зручного середовища.

За винятком зарезервованих для sh, «bash» та особливих параметрів, змінні можна використовувати більш чи менш вільно.

Оскільки багато символів мають подвійне або навіть і потрійне значення, в залежності від контексту, «bash» використовує систему лапок щоб відділити особливе значення таких символів від випадків, коли спеціальне трактування непотрібне.

Bash використовує різні методи розкривання командного рядка щоб визначити, яку саме команду виконувати.

Вправи

Для цієї вправи вам потрібно прочитати довідку для команди useradd, тому що ми збираємось використовувати каталог /etc/skel щоб зберігати стандартні конфігураційні файли оболонки, які копіюються в домашній каталог кожного новоствореного користувача.

Перш за все ми виконаємо кілька загальних вправ по встановленню та відображенню змінних:

  1. Створіть 3 змінні – VAR1, VAR2 і VAR3; ініціалізуйте їх значеннями "thirteen", "13" і "Happy Birthday" відповідно.
  2. Відобразіть значення цих трьох змінних.
  3. Це локальні чи глобальні змінні?
  4. Видаліть VAR3.
  5. Чи зможете ви побачити дві змінні, що залишились, у новому вікні терміналу?
  6. Змініть /etc/profile таким чином, щоб користувачі бачили привітання після реєстрації. Перевірте.
  7. Для користувача root встановіть підказку на кшталт "Danger! Root is doing stuff in \w", бажано яскравого кольору, наприклад червоного чи оранжевого або в реверсному відео режимі.
  8. Переконайтесь, що новостворений користувач також отримав гарну персоналізовану підказку, що інформує його, в якій системі і в якому каталозі він зараз працює. Перевірте ваші зміни, додавши нового користувача та зареєструвавшись від його імені.
  9. Напишіть сценарій, в якому ви двом змінним присвоюєте два цілочисельні значення. Цей сценарій повинен розрахувати площу прямокутника з відповідними сторонами. Він повинен бути забезпечений коментаріями та елегантним виводом.

Не забудьте зробити chmod вашим сценаріям!