bash-huyash
Команды оболочки bash можно выполнять с терминала, из файла (когда первым аргументом передано имя файла) или можно подавать баш скрипты на вход команде bash:
macbook:~ vandud$ echo "echo govno" | bash
govno
macbook:~ vandud$ echo "echo govno" | bash -s
govno
Ключ -i
запустит оболочку и покажет приглашение:
macbook:~ vandud$ bash -i
The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.
bash-3.2$ echo "echo 'mocha i govno'" | bash -s
mocha i govno
bash-3.2$
Исходные оболочки читают содержимое файлов /etc/profile и -/.profile, а обычные оболочки - содержимое переменной окружения $ENV, если она установлена
Исходная оболочка это та которая служит для входа в систему
--init-file
/--rcfile
- переопределить ~/.bashrc
-
$0
- имя сценария -
$1
- первый аргумент -
$N
- N-ный аргумент
macbook:test vandud$ cat test
echo "govno"
macbook:test vandud$ ls -l test
-rw-r--r-- 1 vandud wheel 13 Feb 19 07:22 test
macbook:test vandud$ ./test
-bash: ./test: Permission denied
macbook:test vandud$ bash test
govno
Код завершения команды доступен в переменной $?
Внутренние команды оболочки передают этот код непосредственно оболочке, а внешние команды передают его операционной системе
Значение кода завершения может находиться в диапазоне от 0 до 255
Инит файлы читаются в следующем порядке
- /etc/profile
- Первый найденный из ~/.bash_profile, ~/.bash_login или ~/.profile
- ~/.bashrc читается неисходными оболочками, но не читается если оболочка запущена как sh или с параметром --posix (в этих двух случаях читается $ENV)
При выходе из интерактивной оболочки выполняется ~/.bash_logout (при наличии)
Интересный момент про ссылки
macbook:test vandud$ cat test
echo $0
macbook:test vandud$ ls -lh
total 8
-rwxr--r-- 1 vandud wheel 8B Feb 19 10:22 test
lrwxr-xr-x 1 vandud wheel 4B Feb 19 10:22 test2 -> test
macbook:test vandud$ ./test
./test
macbook:test vandud$ ./test2
./test2
Существует сокращение для получения хомяка пользователя
vandud@macbook test % grep logd /etc/passwd
_logd:*:272:272:Log Daemon:/var/db/diagnostics:/usr/bin/false
vandud@macbook test % echo ~_logd
/var/db/diagnostics
Немного про глоббинг
Базовые штуки
- * - любое кол-во любых символов
- ? - один любой символ
- [a-zA-Z0-9] - один любой символ из перечисленных
- ~ - хомяк
- ~username - хомяк username'a
- ~+ - текущая дира (аналогично pwd)
- ~- - предыдущая дира
Для этих нужно чтоб был включен параметр extglob (в bash он ставится через shopt -s extglob
, в zsh через setopt)
- ?(pattern) - 0-1 вхождений паттерна
- *(pattern) - 0+ вхождений
- +(pattern) - 1+ вхождений
- @(pattern) - точное совпадение с одним паттерном
- !(pattern) - все что точно не шаблон
Шаблонов может быть много, тогда их нужно разделять пайпом
Классы символов (для них тоже требуется extglob)
Указываются в [[:<class>:]]
- alnum - буквоцифры
- alpha - буквы
- ascii - ASCII
- blank - пробелы и табы
- cntrl - управляющие символы
- digit - десятичные цифры
- graph - непробельные
- lower - строчные
- upper - прописные
- print - печатаемые
- punct - знаки препинания
- space - пробелы
- word - то же что и alnum
- xdigit - шестнадцатиричные
Скрипты читаются построчно
Каждая строка сначала читается, потом проверяется на синтаксис, а потом уже выполняется
Поэтому, например, нельзя определить алиас и вызвать его в одной строке
Нужно учитывать аналогичные примеру операции
Подстановки (выше) и раскрытие скобок отличаются
При раскрытии скобок образуется текст, который не обязательно должен совпадать с уже существующими файлами
Есть два варианта раскрытия скобок
vandud@macbook test % echo head{A,B,C}tail
headAtail headBtail headCtail
vandud@macbook test % echo head{A..C}tail
headAtail headBtail headCtail
vandud@macbook test % echo head{1..5..2}tail
head1tail head3tail head5tail
В числовом выражении предел start может предваряться нулями
vandud@macbook test % echo head{001..5..2}tail
head001tail head003tail head005tail
vandud@macbook test % echo head{01..005..2}tail
head01tail head03tail head05tail
По длине числа start будут выровняны раскрытые числа
vandud@macbook test % echo {0..10..5}
0 5 10
vandud@macbook test % echo {00..10..5}
00 05 10
vandud@macbook test % echo {000..10..5}
000 005 010
vandud@macbook test % echo {0000..10..5}
0000 0005 0010
Скобки могут быть вложенными
vandud@macbook test % echo {a,b,{1..4}}
a b 1 2 3 4
vandud@macbook test % echo {a..b..{1..4}}
{a..b..1} {a..b..2} {a..b..3} {a..b..4}
vandud@macbook test % echo {a..b..{1..5..2}}
{a..b..1} {a..b..3} {a..b..5}
Скобки должны быть без кавычек, иначе баш не распарсит
Подстановки команд будут проигнорированы при раскрытии скобок (но у меня в zsh работает, в баше не смог)
vandud@macbook test % echo {1..10..$(echo 3)}
1 4 7 10
vandud@macbook test % echo {1..10..`echo 3`}
1 4 7 10
vandud@macbook test % echo hi{DD,BB,CC,AA}bitch
hiDDbitch hiBBbitch hiCCbitch hiAAbitch
vandud@macbook test % ls LKz{QQ,Qt}e0f
LKzQQe0f LKzQte0f
В качестве элемента внутри скобок может быть и пустота
vandud@macbook test % ls zhopa*
zhopa
vandud@macbook test % mv zhopa{,_s_gavnoy}
vandud@macbook test % ls zhopa*
zhopa_s_gavnoy
Управляющие последовательности распознаются и интерпретируются в след. контекстах
- $'...'
- аргументы в
echo -e
иprintf%b
В кавычках отменяется спец. значение символов, например скобок, стрелок, итд
Внутри двойных кавычек действует доллар и тик
- $ - для подстановки переменных, комманд или арифметики
- ` - для подстановки комманд
Внутри одинарных кавычек все становится обычным текстом
\ - используется для экранирования
- cmd & - в фоне
- { cmd ; cmd ; } - в текущей оболочке
- ( cmd ; cmd ; ) - в подоболочке
- cmd | cmd - пайп
- cmd `cmd` - подстановка (без вложенности)
- cmd $(cmd) - подстановка (возможна вложенность)
- cmd $((cmd)) - арифметика
- cmd1 && cmd2 - выполнить cmd2 только если cmd1 выполнился успешно
- cmd || cmd - выполнить cmd2 если cmd1 сломался
- !cmd - инвертировать код ответа
cmd < filename
vandud@macbook test % cat zhopa_s_gavnoy | cat
asonetuhaoesntuhsanoethustaoehustnaoehusnaeohus
vandud@macbook test % cat < zhopa_s_gavnoy
asonetuhaoesntuhsanoethustaoehustnaoehusnaeohus
vandud@macbook test % cat zhopa_s_gavnoy | grep -o 'aso'
aso
vandud@macbook test % grep -o 'aso' < zhopa_s_gavnoy
aso
То же самое что и выше, только данные берутся не из файла а из текста
cmd << text
vandud@macbook test % cat <<< "niga mazafaka bitch"
niga mazafaka bitch
vandud@macbook test % echo "niga mazafaka bitch" | cat
niga mazafaka bitch
cmd << EOF
vandud@macbook test % cat << ZHOPA | grep -i niga
pipe heredoc> niga1
pipe heredoc> niiga2
pipe heredoc> zhopa
pipe heredoc> ZHOPA
niga1
>| - позволяет перезаписать файл даже если включен параметр noclobber
bash-3.2$ set -o | grep clobber
noclobber off
bash-3.2$ cat test
govno
bash-3.2$ echo "zhopa" > test
bash-3.2$ cat test
zhopa
bash-3.2$ set -o noclobber
bash-3.2$ set -o | grep clobber
noclobber on
bash-3.2$ cat test
zhopa
bash-3.2$ echo "govno" > test
bash: test: cannot overwrite existing file
bash-3.2$ cat test
zhopa
bash-3.2$ echo "govno" >| test # SUCCESS
bash-3.2$ cat test
govno
bash-3.2$
О параметрах
У оболочки есть разные параметры
Один из них упоминался ранее (extglob)
Для просмотра и установки этих параметров можно использовать команду set или shopt
Существует сразу две команды потому что set (и параметры с которыми можно взаимодействовать через него) унаследовался вместе с bourne-style (от sh), а shopt появился в bash. Поэтому некоторые параметры могут быть не видны в одном и видны в другом
Посмотреть текущее состояние можно так
set -o
shopt
Активировать так
set -o noclobber # enable
set +o noclobber # disable
shopt -s extglob # enable
shopt -u extglob # disable
-
cdspell - исправляет опечатки
bash-3.2$ shopt -s cdspell bash-3.2$ ls -lh total 0 drwxr-xr-x 2 vandud wheel 64B Feb 22 18:30 aoeu bash-3.2$ cd aoue aoeu bash-3.2$ pwd /tmp/test/aoeu
-
autocd - по дефолту баш выполняет указанный файл, а эта опция позволяет переходить по переданному пути если передана папка а не файл
root@phobos:/tmp# shopt -s autocd root@phobos:/tmp# /etc cd -- /etc root@phobos:/etc# shopt -u autocd root@phobos:/etc# /etc -bash: /etc: Is a directory
-
histverify - при вводе
!!
не будет выполнять сразуbash-3.2$ shopt -s histverify bash-3.2$ echo "test" test bash-3.2$ sudo !! bash-3.2$ sudo echo "test" ^C # ВОТ bash-3.2$ shopt -u histverify bash-3.2$ echo "test" test bash-3.2$ sudo !! # А ТУТ СРАЗУ ПРИМЕНИЛО sudo echo "test" Password:
Параметров всяких целая куча, тут парочку показал для примера
Перенаправление вывода по дескриптору
- stdoud направить в файл с дескриптором n
cmd >&n
- (stdout + то что cmd пишет в файл с дескриптором m) направить в файл с дескриптором n
cmd m>&n
- закрыть stdout
cmd >&-
Пробел между стрелкой и ФД не нужен
stderr в stdout
root@mars:/var/tmp/test# nginx 2>&1 | tee nginx.out
root@mars:/var/tmp/test# nginx |& tee nginx.out
No Comments