zsh
Вставка последнего измененного файла в zsh
Недавно обнаружил у себя в хоткеях zsh этакое
$ bindkey
...
"^Xm" _most_recent_file
...То есть если нажать Ctrl-x m, в командную строку вставится имя файла который менялся последним в текущей директории. Активно использую, вот несколько примеров использования:
Автодополнение из истории директорий в zsh
Если в zsh набрать cd - и нажать Tab, то появится менюшка выбора директорий в которых ты уже побывал.
$ cd bin $ cd ~/tmp $ cd /usr/src/linux $ cd -<TAB> directory stack 1 -- /home/ramok/tmp 2 -- /home/ramok/bin 3 -- /home/ramok
Линки в тему:
- переход в предыдущий work dir
- WCD - Wherever Change Directory
- Расширенные возможности команды cd в zsh
- Удобное обращение к родительским каталогам в zsh
- Еще более удобное обращение к родительским каталогам в zsh
- Удобные alias для работы с временными директориями
Как сравнить два бинарных файла
К сожалению я не знаю нормального способа визуального сравнения двух бинарных файлов (что бы нормально отображалось "выпадение байта").
Тем неменее имея zsh и vim, сравнить по быстрому два бинарных файла можно так
$ vim -d =(xxd -g 1 файл1) =(xxd -g 1 файл2)Объяснения:
- vim -d - diff режим vim-а, он же запускается командой vimdiff
- =(xxd -g 1 файл1) - это конструкция zsh, запускает команду внутри =(), сохраняет вывод этой команды во временный файл, и подставляет его имя вместо этой конструкции.
Линки в тему:
- Как съесть один пирог дважды: bash, tee, process substitution
- Нелинейные конвейеры
- Чем отличаются уровни оптимизации -O в gcc?
Информация о VCS (Version Control Systems) в приглашении zsh
При переходе на git пришла в голову мысль что было бы удобно видеть в приглашении zsh в каком состоянии локальный репозиторий.
Всевозможные rebase, am, merge и подобное сбивает с толку.
Сказано - сделано. Написал собственный велосипед. Потом нашел еще парочку велосипедов в интернете, разобрал на запчасти и прикрутил к своему велосипеду новенькие колеса и смазал педали. Но вскоре, к своему стыду, в мане zsh увидел уже готовый даже не велосипед, а целый танк с экипажем. И собакой в придачу.
Вот он
$ PAGER=less LESS='-p VERSION CONTROL SYSTEMS' man zshallТворчески переосмыслив пример из мана вот что получилось
autoload -Uz vcs_info # включаем только git svn svk cvs. Возможные VCS можно посмотреть командой vcs_info_printsys zstyle ':vcs_info:*' enable git svn svk cvs # домашняя директория из CVS репозитория. Исключаем ее и некоторые директории из домашнего репозитория zstyle ':vcs_info:*' disable-patterns "$HOME(|/.*|/bin)" # Модифицированная версия из man zshcontrib, добавлены флажки staged и unstaged изменений zstyle ':vcs_info:*' actionformats '%F{5}(%f%s%F{5})%F{3}%m%F{5}[ %F{2}%b%F{3}|%F{1}%a%F{5}][ %B%F{yellow}%c%F{red}%u%%b%F{5}]%f ' zstyle ':vcs_info:*' formats '%F{5}(%f%s%F{5})%F{3}%m%F{5}[ %F{2}%b%F{5}][ %B%F{yellow}%c%F{red}%u%%b%F{5}]%f ' zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat '%b%F{1}:%F{3}%r' zstyle ':vcs_info:*' check-for-changes true zstyle ':vcs_info:*' get-revision true setopt prompt_subst RPROMPT=$'${vcs_info_msg_0_}%b%F{cyan}%T%f'
Ну и как всегда: Live demo! Ж:-)
Расширеные маски файлов в zsh. Сортировка по времени доступа.
Лично я часто использую для различных задач сортировку по времени модификации в масках файлов.
Например:
Просмотреть скриншоты по маске ~/pics/desktop-200* отсортированные по времени модификации (самые новые, будут идти первыми).
$ feh ~/pics/desktop-200*(om)Что бы запомнить:
o от order - порядок
m от modification time - время модификации
Просмотреть последний скриншот
$ feh ~/pics/*(om[1])Залить последние четыре фотографии с мобилы на хостинг по scp
$ scp ~/photo/mobile/se_24/*(om[1,4]) core.org.ua:~/www/data/tmp/se_24/Почистить немного места в /tmp удалив пару самых старых подкаста
$ rm /tmp/echo.msk.ru/*(Om[1,2])PS
Подробнее о спецификаторах к маскам файлов можно узнать в man zshexpn в разделе Glob Qualifiers
$ PAGER=less LESS=-p'Glob Qualifiers' \man zshexpnPersistent ZSH aliases (в bash тоже можно :)
Три уровня реальности.
Нулевой. В незапамятные времена я вынес определение aliases из .zshrc в другой файл, .zsh_aliases. Это разгрузило и без того тучный .zshrc, в котором остался только вызов
if [[ -f $ZDOTDIR/.zsh_aliases ]] { . $ZDOTDIR/.zsh_aliases; }
Первый. Теперь .zsh_aliases можно обрабатывать автоматически! Допустим, я по ходу работы придумал полезный alias. Но вот отвлекаться для редактирования .zsh_aliases не хочется. Что за беда? сделал alias с именем mkalias:
mkalias='alias | grep -v "='\''LC_ALL" | sed "s/^/alias /" > ~/.zsh_aliases'
Теперь зафиксировать сделанные в списке alias-ов изменения можно одной командой. И даже вставить её в .zlogout, чтобы управиться с задачей за 0 команд :).
Второй. А что это за "grep" такой лишний в mkalias? А это вот что. Есть несклько команд, которые я хочу запускать не в кодировке по умолчанию, а в другой. Например, man-ы хочу читать по-английски. Или GTK1-программы -- в кодировке всегда KOI8-R. Или, наоборот, stardict-gtk всегда в кодировке UTF-8. Помогает проставить LC_ALL: LC_ALL=соответств_кодировка команда, но лучше это превратить в alias. Вот у меня и заведены файлы .locale.кодировка, которые читаются из .zshrc так:
# alias some LC_ALL changes when running command for N ($ZDOTDIR/.locale.*) { T="${N##*.locale.}" for F (`cat $N`) alias "$F"="LC_ALL=$T $F" } || :
Так что строчки с '="LC_ALL' запоминать не надо, они генерируются. Отсюда и grep -v в mkalias. Более того, .zshrc и .zsh_aliases у меня на всех машинах одинаковые (и на Linux разных конфессий, и на FreeBSD разных версий). А вот .locale.* -- везде разный, т. к. на некоторых машинах по умолчанию стоит одна кодировка, на некоторых -- другая, там одни программы капризничают, тут другие.
Каким способом .zshrc и .zsh_aliases у меня на всех машинах получаются одинаковые? А это к alias-ам отношения не имеет.
Различные стили автодополнения в командной строке vim
Для тех кто хочет в командной строке vim автодополнение файлов как в bash заносим в ~/.vimrc
set wildmode=longest,list
При нажатии Tab имя файла дополнится до наибольшего совпадения и выведет список альтернатив.
Мне больше нравится автодополнение как в моем zsh
set wildmode=list:longest,full
подробности :help wildmode
Использование списка аргументов в bash и zsh в интерактивном режиме
Как то был совет "Вставка последнего аргумента предыдущей команды в bash и zsh." который показывает как более эффективно работать в командной строке.
Но он не поможет если вам нужен не один аргумент, а несколько. В этом совете представлен пример работы когда многим командам нужно указывать как параметр имена нескольких файлов.
Для этого используется механизм передачи параметров, который позволяет ссылаться на параметры с помощью переменно $@.
Задача: создать два скрипта, дать им права и добавить их в cvs репозиторий.
Алиас для показа самых больших файлов и директорий в текущей директории
"Резиновый винчестер это не игрушка, это мечта" Ж:-)
Как всегда не хватает места, и при поиске чего бы такого удалить может помочь алиас который показывает файлы и директории которые занимают больше мегабайта.
для bash, заносим в ~/.bashrc
alias dud="(shopt -s dotglob;du -ks * | sort -nr | sed -e 's/^\([0-9]\{1,\}\)[0-9]\{6\}[^0-9]/\1G\t/;t;s/^\([0-9]\{1,\}\)[0-9]\{3\}[^0-9]/\1M\t/;t;d')" #или альтернативный вариант с perl alias dud="(shopt -s dotglob;du -ks * | sort -nr | perl -pe 's/^(\d+)\d{6}[^\d]/\$1G\t/ || s/^(\d+)\d{3}[^\d]/\$1M\t/ || s/.*\n//')"
для zsh, заносим в ~/.zshrc
alias dud="(setopt globdots;du -ks * | sort -nr | sed -e 's/^\([0-9]\{1,\}\)[0-9]\{6\}[^0-9]/\1G\t/;t;s/^\([0-9]\{1,\}\)[0-9]\{3\}[^0-9]/\1M\t/;t;d')" #или альтернативный вариант с perl alias dud="(setopt globdots;du -ks * | sort -nr | perl -pe 's/^(\d+)\d{6}[^\d]/\$1G\t/ || s/^(\d+)\d{3}[^\d]/\$1M\t/ || s/.*\n//')"
Цифры примерные, так как считается что в мегабайте не 1024 байт, а 1000.
Пример использования:
Настройка функциональных клавиш в ZSH
Как единообразно задействовать функциональные клавиши в zsh на различных терминалах
выполнение команды в zsh в зависимости от синтаксиса введённой строки
Бывает так, что надоедает дописывать к началу скопированной в терминал, к примеру, из браузера, ссылки, саму команду, которая должна эту ссылку обработать. Например, вот так (где | - текущее положение курсора):
> |<c-v> > git://github.com/pieter/git-bzr.git|<home> > git clone |git://github.com/pieter/git-bzr.git
Если Вам это знакомо, то Вы понимаете, о чём я. Причём речь не обязательно о git:// для git clone; это может быть lp: или bzr:// для bzr branch, http:// - для wget или aria2c, file:/// - для cd ну и т.д. и т.п. - вариантов множество и примеры использования могут зависеть от того, с какими видами пар ссылка/действие приходится работать. Конечно, можно настроить короткие алиасы для команд, но можно и пойти чуть дальше - можно настроить, что же должен выполнить zsh в зависимости от синтаксиса введённой строки. Для этого нужно отредактировать .zshrc файл, добавив туда функцию precmd (чуть подробнее про precmd можно прочитать в комментариях к коду в этом совете - http://linsovet.com/content/настройка-приглашений-zsh) примерно следующего содержания:
Как съесть один пирог дважды: bash, tee, process substitution
Задача проста: обработать один стандартный ввод с помощью двух (или более) фильтров.
Тривиальное решение: сохранить ввод в файл и потом его дважды обработать.
$ some_cmd > tmp_file; filtr1 < tmp_file; filtr2 < tmp_file; rm tmp_fileСуществует однако полезная программа tee, которая умеет свой стандартный ввод записывать в много разных мест. Вот бы взять да и отослать результат не в разные файлы, а послать на вход разным процессам! Если в bash разрешена такая штука как process substitution, то это вполне возможно.
Пример: выведем список юзеров, у которых логин-шелл установлен в /bin/bash, а также число таких юзеров.
$ grep /bin/bash /etc/passwd | tee >(wc -l)Здесь мы составили нужный список с помощью grep, размножили его с помощью tee и одну из копий подали на вход команде wc -l, которая сосчитает количество строк. Пример, конечно, игрушечный, но общая идея должна быть ясна :)
Защита от случайной перезаписи содержимого файла
Защита от случайной перезаписи содержимого файла.
Любой знающий основы шела знает как можно создать файл с помощью перенаправления ввода/вывода
$ echo какой то текст > test.txt $ cat test.txt какой то текст
Но если в файле test.txt был не пустой то содержимое файла перепишется, и восстановить его уже не удастся.
В bash от такого можно защитится с помощью установки опции set -o noclobber
$ set -o noclobber $ echo другой текст > test.txt bash: test.txt: не могу переписать уже существующий файл $
Если вы знаете что делаете, и хотите переписать файл то можно или отменить эту опцию или воспользоваться специальной формой перенаправления >|
$ set +o noclobber #или $ echo тест >| test.txt
В zsh аналогичные опции выглядят так
$ setopt clobber $ setopt noclobber
И кроме привычного >| есть другая форма >!
$ echo тест >! test.txt $ echo тест >| test.txt
настройка приглашений zsh
Бывает так, что, работая бОльшую часть времени только с одной учётной записи и с одного хоста, осознаешь бессмысленность раздутого на пол-экрана терминала приглашения командной строки наподобие
myuseraccount@mycomputer:/path/to/some/folder $
Зная, что в zsh можно задействовать второе приглашение, справа и, умея пользоваться гуглом, проковырявшись с настройкой конфига, хотелось бы поделиться куском скрипта, который, скопировав в .zshrc, будет делать следующее:
зайти в screen на удалённой системе
Требуется: Приатачиться к screen, запущенному на удалённой системе с минимальным количеством телодвижений.
Решение:
Не обязательно, но все таки:
1. делаем беспарольную аутентификацию как рассказно здесь
затем
2.
$ ssh -t login@host 'source .bashrc; screen -x'Готово!
3. И на последок, что бы все вышеперечисленное таки совершалось с наименьшим количеством телодвижений, создаем скрипт:
$ cat >remotescreen !#/bin/sh ssh -t login@host 'source .bashrc; screen -x' $chmod 755 remotescreen
3.a ... или делаем алиас в любимом .*shrc
alias remotescreen="ssh -t login@host 'source .bashrc; screen -x'"P.S. в пункте 2 заменить .bashrc на соответствующий .zshrc, итд...
zsh + mc
Давно читаю советы с этого сайта за что всем спасибо.
Вроде нигде такой совет не проскакивал, в общем мой совет:
В zsh я пользуюсь темой приветствия adam2
на днях решил её поправить чтобы показывала не только директорию и пользователя с именем машины но и кое что ещё
но не это важно, а то что за одно я решил избавиться от старого глюка связанного с этой темой,
а именно с проблемой потери размера консоли
.-(~)---------------------------------------------------------------------------------------------------------(denis@tentorium)- `--> .-(~)---------------------------------------------------------------------------------------------------------(denis@tentorium)- `--> `--> .-(/var/cache/dictionaries-common)---------------------------------------------------------------------------------------------- -----------(denis@tentorium)- `-->
т.е. после запуска mc и перехода в /var/cache/dictionaries у нас приглашение съехало.
Быстрый перезапуск команды с дополнительным параметром
В продолжении темы об использовании ссылки на предыдущую команду.
Часто при копировании директорий забываю добавлять флажок -r. Выручает !!.
/media/cd/$ cp SST_SDA /usr/local/dump/tmp cp: пропуск каталога `SST_SDA' /media/cd/[1] $ !! -r cp SST_SDA /usr/local/dump/tmp -r /media/cd/$
Вставка последнего аргумента предыдущей команды в bash и zsh
В bash и zsh в стандартном режиме (он же зовется emasc-режим, это тот который не vi-режим Ж:-)
есть удобное сочетание клавиш Esc-. позвляющее вставлять последнее слово аргументов прошлой команды.
Пример использования. Например прочитали новость о выходе нового релиза игрушки glest и решили глянуть что за зверь такой.
# так как лень, то ищем есть ли в репозитории $ apt-cache search glest glest-data - A free 3d real-time customizable strategy game glest - A free 3D real-time customizable strategy game # o, есть. смотрим описание и зависимости $ apt-cache show Esc-. Package: glest ... Depends: glest-data (= 3.1.0-1), .. ... Description: A free 3D real-time customizable strategy game Glest takes place in a context which could be compared to that of the pre-renaissance Europe, with the licence that magic forces exist in the environment and can be controlled. # ок. устраивает установим $ sudo apt-get install Esc-. Чтение списков пакетов... Готово Построение дерева зависимостей Reading state information... Готово ... # смотрим что поставилось, какие запусные файлы, есть ли мануалы, README.Debian и что там $ dpkg -L Esc-. /. /usr /usr/games /usr/games/glest ... # ну и запустим $ Esc-.
Как видно из примера не плохо облегчает жизнь Ж:-)
Если вы используете zsh в vi режиме, то получить эту фичу в режиме вставки можно добавив в свой ~/.zshrc
bindkey -M viins '^[.' insert-last-word
Только учтите что между нажатием Esc и . должно пройти меньше секунды, иначе zsh перейдет в командный режим vi-режима.
Подсветка потока ошибок в zsh
Часто сообщения об ошибках теряются в общем потоке вывода данных, и их хотелось бы как нибуть выделять. Тут опять пригодятся глобальные алиасы zsh.
Добавим в ~/.zshrc
autoload colors # подключим цвета colors alias -g HE='2>>( sed -ue "s/.*/$fg_bold[red]&$reset_color/" 1>&2 )' # Highlight Errors
После перезагрузки zsh у нас появится глобальный алиас HE который можно использовать на ряду с другими фильтрами. Алиас запускает в фоне sed который подсвечивает строки, и перенаправляет ему в на выход стандартный поток ошибок
Пример работы: мы хотим найти в /etc все файлы в названии которых есть zsh и при этом подсветить в каких каталогах поиск не удался.

Пояснения: строка
$ find /etc HE GI zshРазвернется в
find /etc 2>>( sed -ue "s/.*/$fg_bold[red]&$reset_color/" 1>&2 ) | grep -i zsh
Глобальный алиас GI описан здесь.
Подсведка результатов grep описана здесь
BUGS: алиас запускает асинхронный процесс подсведки цветов, что обозначает что подсвеченые ошибки могут выводится не синхронно с потоком стандартного вывода.
PS
Для пользователей bash существует полезный скрипт по подсвечиванию потока ошибок для программы переденной как параметр.


