Перевод поста Brian Storti “Understanding Shell Script’s idiom: 2>&1”
Идиома — устойчивое выражение, поговорка или речевой оборот, понятный всем носителям языка. Перевести идиому можно, но понять, о чем идет речь, человеку, который изучает данный язык в качестве иностранного, будет трудно, потому что значение идиомы не вытекает из значения ее слов.
Идиома программирования — устойчивый способ выражения некоторой составной конструкции в одном или нескольких языках программирования. Идиома является шаблоном решения задачи, записи алгоритма или структуры данных путём комбинирования встроенных элементов языка.
Работая с языком программирования или сценариев, мы постоянно используем
некоторые идиомы — конструкции, которые выполняют определенные действия,
решают какую-то распространенную задачу. В скриптах оболочки довольно
распространенной и не всегда хорошо понимаемой идиомой является 2>&1
, как в
примере ls foo > /dev/null 2>&1
Позвольте мне объяснить, что здесь
происходит и почему это работает именно так.
Перенаправление — это механизм, используемый для отправки вывода команды в
другое место. Например, если мы применяем команду cat
к файлу, то вывод этой
команды по умолчанию будет отображаться на экране:
$ cat foo.txt
foo
bar
baz
Мы можем перенаправить этот вывод в другое место, например, в файл output.txt:
$ cat foo.txt > output.txt
$ cat output.txt
foo
bar
baz
Отметим, что после первого выполнения команды cat
на экран ничего не было
выведено, так как мы изменили размещение стандартного выходного потока
(stdout
) с экрана на файл.
Также важно знать, что есть стандартный поток ошибок (stderr), в который
консольные программы посылают сообщения о возникающих ошибках. Например,
попытаемся применить команду cat
к несуществующему файлу:
$ cat nop.txt > output.txt
cat: nop.txt: No such file or directory
Несмотря на то, что мы перенаправили stdout
в файл, мы по-прежнему видим
сообщения об ошибках на экране. Это правильно, так как мы перенаправили только
выходной поток, а не поток ошибок.
Дескриптор файла — это положительное целое число, которое операционная система назначает открытому файлу. Если у вас открыто 100 файлов, то для них будут созданы 100 дескрипторов.
Замечание. В Unix-системах все является файлом, в том числе стандартные потоки
ввода и ошибок. Поэтому для потоков stdout
и stderr тоже определены файловые
дескрипторы, причем с фисксированными номерами: 1 для sdtout и 2 для stderr.
Вернемся к нашему первому примеру с перенаправлением cat foo.txt
в файл
output.txt. Теперь мы можем переписать эту команду так:
$ cat foo.txt 1> output.txt
Здесь число 1 означает файловый дескриптор для stdout
.
Аналогичным образом, чтобы перенаправить поток ошибок stderr
, нужно перед
оператором перенаправления >
указать файловый дескриптор с номером 2:
# Использование файлового дескриптора (2) потока stderr для перенаправления сообщений об ошибках в файл
$ cat nop.txt 2> error.txt
$ cat error.txt
cat: error.txt: No such file or directory
Теперь вы уже, наверное, догадываетесь, что делает идиома 2>&1
?
Запись &1
означает значение файлового дескриптора 1 (stdout
). Поэтому
выражение 2>&1
означает, что stderr
(2) перенаправляется в то же место,
куда был перенаправлен stdout
(1):
$ cat foo.txt > output.txt 2>&1
$ cat output.txt
foo
bar
baz
$ cat nop.xt > output.txt 2>&1
$ cat output.txt
cat: nop.txt: No such file or directory
stdout
) и стандартный поток ошибок (stderr
).stdout
соответсвует файловый дескриптор 1, потоку stderr
— файловый дескриптор 2.command > output
является сокращением для command 1> output
.&[FILE_DESCRIPTOR]
.2>&1
перенаправит stderr
туда же, куда направлен stdout
.Комбинация | Мнемоника | Описание | Плагин |
---|---|---|---|
H | High | Перейти в верхнюю строку экрана | |
L | Low | Перейти в нижнюю строку экрана | |
M | Middle | Перейти в среднюю строку экрана | |
<Enter> |
Перейти на первый символ следующей строки | ||
+ | Перейти на первый символ следующей строки | ||
- | Перейти на первый символ предыдущей строки | ||
<L-L>s{c} |
Подсветка символа {c} на всем экране |
easymotion/vim-easymotion | |
<L-L>f{c} |
Подсветка символа {c} от курсора до конца экрана |
easymotion/vim-easymotion | |
<L-L>F{c} |
Подсветка символа {c} от курсора до начала экрана |
easymotion/vim-easymotion |
Комбинация | Мнемоника | Описание |
---|---|---|
zt | zTop | Переместить текущую строку вверх экрана |
zb | zBottom | Переместить текущую строку вниз экрана |
zz | Переместить текущую строку в середину экрана | |
<C-f> |
Forward | Пролистать вперед на один экран |
<C-b> |
Backward | Пролистать назад на один экран |
<C-d> |
Down | Пролистать вниз (вперед) на полэкрана |
<C-u> |
Up | Пролистать вверх (назад) на полэкрана |
<C-e> |
Пролистать вниз (вперед) на одну строку | |
<C-y> |
Пролистать вверх (назад) на одну строку |
Комбинация | Описание |
---|---|
`{mark} | Перейти к метке {char} |
`[ | Перейти к началу последнего изменения или вставки |
`] | Перейти к концу последнего изменения или вставки |
`< | Перейти к началу последнего выделения, сделанного в визуальном режиме |
`] | Перейти к концу последнего выделения, сделанного в визуальном режиме |
`. | Перейти к месту последнего изменения |
`^ | Перейти к месту последней вставки |
`` | Вернуться в позицию перед последним переходом в текущем файле |
Если вместо ` нажать ‘, то переход происходит к началу строки, содержащей метку.
Комбинация | Мнемоника | Описание | Плагин |
---|---|---|---|
Buffer Explorer | Открыть Buffer Explorer | jlanzarotta/bufexplorer | |
Buffer Toggle | Открыть/закрыть Buffer Explorer | jlanzarotta/bufexplorer | |
Buffer Split | Горизонтальный сплит для Buffer Explorer | jlanzarotta/bufexplorer | |
Buffer Vertical Split | Вертикальный сплит для Buffer Explorer | jlanzarotta/bufexplorer |
Обозначение | Описание | Плагин |
---|---|---|
ae | Весь файл (буфер) | kana/vim-textobj-entire |
Обозначение | Описание | Плагин |
---|---|---|
jq{motion} | Форматирование текста по ширине. Ширина задается :set textwidth=80 |
перевод статьи mike kozlowski “why atom can’t replace vim”
Описание настройки SSH для работы с одним или двумя профилями на GitHub без ввода пароля для авторизации.
Свежую версию vifm можно установить из исходников на официальном сайте проекта или в репозитории GitHub.
Установка с сайта https://vifm.info/downloads.shtml :
sudo apt-get install libncursesw5-dev
./configure
make
sudo make install
Также можно установить из репозитория GitHub. Скрипт для установки:
#!/bin/sh
mkdir vifm_source
cd vifm_source
git clone https://github.com/vifm/vifm.git .
sudo apt-get install -y libncursesw5-dev
./configure
make
sudo make install
cd ..
rm -rf vifm_source
Запуск установленной утилиты - команда vifm
.
После установки vifm неактивная панель может выделяться белым цветом, а имена файлов в ней могут быть выделены подчеркиванием. Выглядит некрасиво, чтобы убрать, нужно изменить настройки в файле с параметрами цветов для vifm.
:e $VIFM/colors/Default.vifm