Восемь малоизвестных опций Bash

Автор оригинала: Ian Miell
  • Перевод
  • Tutorial
Некоторые опции Bash хорошо известны и часто используются. Например, многие в начале скрипта пишут

set -o xtrace

для отладки,

set -o errexit

для выхода по ошибке или

set -o errunset

для выхода, если вызванная переменная не установлена.

Но есть много других опций. Иногда они слишком путано описаны в манах, поэтому я собрал здесь некоторые из наиболее полезных, с объяснением.

Примечание: на Mac может стоять более старая версия bash (3.x, а не 4.x), где не все эти опции доступны. В этом случае смотрите здесь или здесь.

set или shopt?


Есть два способа установки параметров bash: из скрипта или из командной строки. Можно использовать встроенные команды set и shopt. Обе изменяют поведение оболочки, делают во многом одно и тоже (с разными аргументами), а различаются своим происхождением. Параметры set наследуются или заимствуются из параметров других оболочек, в то время как параметры shopt созданы в bash.

Если хотите посмотреть на текущие опции, запустите:

$ set -o
$ shopt

Для активации опции в set используется длинный или короткий синтаксис:

$ set -o errunset
$ set -e

Эффект одинаков.

Чтобы отключить опцию, нужно поставить плюс вместо минуса:

$ set +e

Долгое время я не мог запомнить этот синтаксис, поскольку логика кажется неправильной (минус включает опцию, а плюс — отключает).

В shopt для включения и отключения опций используются (более логичные) флаги -s (set) и -u (unset):

$ shopt -s cdspell # <= on
$ shopt -u cdspell # <= off

Изменение каталогов


Есть несколько опций, которые помогают работать с каталогами.

1. cdspell


С такой настройкой bash начнёт понимать опечатки и будет переносить вас в папку, название которой вы набрали с ошибкой.

$ shopt -s cdspell
$ mkdir abcdefg
$ cd abcdeg
abcdefg
$ cd ..

Я использовал эту опцию много лет, и очень редко (возможно, раз в год) она принимает очень странное решение. Но зато в остальные дни cdspell экономит время, буквально каждый день.

2. autocd


Если вы не готовы мириться с неэффективностью многократного ввода cd, то можете установить эту опцию для перемещения в папку Х, если команда Х не существует.

$ shopt -s autocd
$ abcdefg
$ cd ..

В сочетании с автозаполнением это позволяет быстро прыгать по папкам:

$ ./abc[TAB][RETURN]
cd -- ./abcdefg

Только не называйте папку rm -rf * (да, кстати, это возможно).

3. direxpand


Это классная опция, которая расширяет переменные среды по нажатию Tab:

$ shopt -s direxpand
$ ./[TAB]     # заменяется на...
$ /full/path/to/current_working_folder
$ ~/[TAB]     # заменяется на...
$ /full/path/to/home/folder
$ $HOME/[TAB] #  заменяется на...
$ /full/path/to/home/folder

Чистый выход


4. checkjobs


Этот параметр останавливает выход из сеанса, если в фоновом режиме ещё выполняются задания.

Вместо выхода выводится список незавершённых заданий. Если вы всё равно хотите выйти, то ещё раз введите exit.

$ shopt -s checkjobs
$ echo $$
68125             # <= ID процесса для оболочки
$ sleep 999 &
$ exit
There are running jobs.
[1]+  Running                 sleep 999 &
$ echo $$
68125             # <= ID процесса для оболочки тот же
$ exit
There are running jobs.
[1]+  Running                 sleep 999 &
$ exit
$ echo $$
$ 59316           # <= на этот раз ID процесса  изменился

Сверхспособности по подстановке


5. globstar


Эта опция даёт вам сверхспособности по подстановке! Если ввести:

$ shopt -s globstar
$ ls **

тогда оболочка покажет рекурсивно все каталоги и подкаталоги.

В сочетании с direxpand можно быстро просматривать всё, что ниже в иерархии:

$ shopt -s direxpand
$ ls **[TAB][TAB]
Display all 2033 possibilities? (y or n) 

6. extglob


Эта опция активирует функции, которые чаще ассоциируются с регулярными выражениями. Иногда это очень полезно:

$ shopt -s extglob
$ touch afile bfile cfile
$ ls
afile bfile cfile
$ ls ?(a*|b*)
afile bfile
$ ls !(a*|b*)
cfile

Здесь шаблоны помещаются в круглые скобки и разделяются вертикальной чертой. Вот доступные операторы:

? = соответствует нулю или одному вхождению заданных шаблонов
! = показать всё, что не соответствует заданным шаблонам
* = ноль или более вхождений
+ = одно или более вхождений
@ = ровно одно вхождение

Защита от несчастных случаев


7. histverify


Поначалу может быть немного страшновато использовать использовать быстрый запуск команд из истории сокращениями !! и !$.

Опция histverify позволяет сначала посмотреть, как Bash интерпретирует команду до того, как он на самом деле запустится:

$ shopt -s histverify
$ echo !$          # <= По нажатию Enter команда не запускается
$ echo histverify  # <= Она сначала демонстрируется на экране,
histverify         # <= а потом запускается 

8. Noclobber


Опять же, для защиты от несчастных случаев, а именно от перезаписи файла, который уже существует с оператором редиректа (>). Это может стать катастрофой, если у вас нет резервной копии.

Опция set -С запрещает такую перезапись. В случае необходимости можно обойти защиту с помощью оператора >|:

$ touch afile
$ set -C
$ echo something > afile
-bash: afile: cannot overwrite existing file
$ echo something >| afile
$
Поддержать автора
Поделиться публикацией

Похожие публикации

Комментарии 13

    +1

    Что-то не увидел опций xv:
    set -xv

      0
      А зачем? Они же для пользователя примерно взаимоисключающие? Та и та выводит запускаемые команды, только немного по-разному.

      (ну и set -буква в статье не упоминается потому что она про малоизвестные, а не те, что в каждом скрипте встречаются)
      +1
      Я когда-то любил читать wiki.bash-hackers.org, и даже немножко переводил xgu.ru/wiki/shopt
        +2
        С такой настройкой bash начнёт понимать опечатки и будет переносить вас в папку, название которой вы набрали с ошибкой.


        Извиняюсь, но не понимаю. В разы быстрее и логичнее набирать названия каталогов с использованием автоподстановки через Tab. В таком случае ошибки исключены. Если кто-то набирает с ошибками, значит он не использует автоподстановку. Но почему?
          +2
          Похоже, автор оригинала не потрудился проверить о чём пишет…

          set -e это на самом деле эквивалент set -o errexit
          — опции errunset не существует в природе, есть nounset и её эквивалент set -u.
            +1
            как гуглить синтаксис баша? В языке настолько много разных знаков препинания, что забываешь половину, стоит только сделать перерыв в пару месяцев.
              0
              Еще я бы посоветовал всем утилитку z — это такой cd, который переходит в нужную директорию по неполной информации и с учетом того, как часто вы в этой директории бывали раньше.
                +1
                Написали бы лучше про 'set -o pipefail'. А то 90% выпендривающихся своим башем об это опции не знают.
                  0
                  По привычке пишу классические sh-скрипты, с башем не знаком. Стоит ли переходить на bash?
                  • НЛО прилетело и опубликовало эту надпись здесь
                    +1
                    cdspell

                    Как по мне — вредная опция.
                    К примеру:
                    mkdir abcdefg
                    cd abcdeg
                    rm -rf *
                    

                    сто раз я удалю файлы из каталога abcdefg, а потом в текущем каталоге окажется папка abcdeg…

                    Все таки скрипт должен делать то, что я попросил, а не то что имел ввиду.
                      +1
                      «Защитные» опции (типа histverify, noclobber) могут быть опасны. Привыкнешь, что такие-то операции у тебя на компе можно выполнять безопасно, а потом где-нибудь на удалённом сервере стартанёшь по привычке sudo !!, чтобы посмотреть и подправить команду, а оно вместо вывода текста возьмёт и сразу всё выполнит…
                        0
                        Чтобы отключить опцию, нужно поставить плюс вместо минуса:

                        Логично, прямо как vertical/horizontal split в tmux.

                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                        Самое читаемое