zsh
Повторить символ заданное количество раз
Повторить символ заданное количество раз
$ printf 'A%.0s' {1..50} AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA $ perl -e 'print "A"x50' AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA $ python -c 'print "A"*50' AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Передача файлов по сети в zsh
Когда то тут был совет как копировать файлы по сети между компьютерами с помощью netcat и tar.
zsh умеет заменять netcat:
На хосте который будет применят файлы слушаем порт 1111, и вывод пренаправляем на распаковывающий tar
host1$ zmodload -i zsh/net/tcp && ztcp -ld3 1111 && ztcp -ad4 3 && tar zvxp <&4 && ztcp -c 3 && ztcp -c 4На хосте откуда хотим передавать файлы отправляем на host1 запакованные файлы в директории $DIR
host2$ zmodload -i zsh/net/tcp && ztcp -d3 $HOST1 1111 && tar zc $DIR >&3 && ztcp -c 3Как в zsh удалить битые символические ссылки
В каталоге с активной разработкой могут накапливатся битые символические линки.
Их видно по ls -l.
Удалить их всех разом в zsh можно так
$ rm *(-@)Фортунки для zsh
Нашел неплохую подборку советов по zsh.
Что бы постепенно оставивать решил выводить случайный совет при старте каждого шела
$ mkdir ~/.fortunes $ cd ~/.fortunes $ wget http://www.strcat.de/tmp/zsh-fortunes.tar.gz $ tar xf zsh-fortunes.tar.gz
В ~/.bashrc или ~/.zshrc прописываем
if [ -x "`which fortune`" ]; then if [ -f ~/.fortunes/zsh-fortune/zsh-fortunes ]; then FDB="$FDB .fortunes/zsh-fortune/zsh-fortunes" fi # если debian, то показывать идущие с пакетом fortunes-debian-hints if [ -f /etc/debian_version ]; then FDB="$FDB debian-hints" fi [ "$FDB" ] && eval fortune -e $FDB fi
Вставка последнего измененного файла в 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' # в zsh >= 4.3.11 можно add-zsh-hook precmd vcs_info precmd () { vcs_info }
Ну и как всегда: 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, итд...


