Info
Content

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
Preview_2021-02-19-07-29-58.png


Инит файлы читаются в следующем порядке

  1. /etc/profile
  2. Первый найденный из ~/.bash_profile, ~/.bash_login или ~/.profile
  3. ~/.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

Terminal_2021-02-19-17-09-25.png


В кавычках отменяется спец. значение символов, например скобок, стрелок, итд
Teampaper-Snap_2021-02-19-17-29-21.png
Teampaper-Snap_2021-02-19-17-29-35.png


Внутри двойных кавычек действует доллар и тик

  • $ - для подстановки переменных, комманд или арифметики
  • ` - для подстановки комманд

Внутри одинарных кавычек все становится обычным текстом

\ - используется для экранирования


  • 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
    

    Feb-24-2021-03-29-58.gif

  • 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
Back to top