zsh


ramok аватар

Трассировка скриптов

Во время отладки скриптов очень удобно видеть какие трассировку, какие команды исполняются во время исполнения скрипта.
Обычно это реализуется специальными командами включения/выключения трассировки. Информация о выполнении команд обычно выводится в поток ошибок.
Ниже приведены примеры для sh/bash/zsh, expect/tcl, python.

0
Ваша оценка: Ничего
ramok аватар

Удалить сломаные символические ссылки

Удалить все сломаные символические ссылки в текущей директории и поддиректориях
bash

find . -type l ! -xtype f ! -xtype d -delete

zsh

rm **/*(-@)
0
Ваша оценка: Ничего
romy4 аватар

Фильтрация stderr без слития с stdout

Сделав два раза swap и между ними grep - мы добиваемся желаемого, фильтруем stderr (почти) без побочных эффектов.

( prog 3>&2 2>&1 1>&3 | grep -v "лишний warning который нельзя отключить" ) 3>&2 2>&1 1>&3

----------------
ликбез:
Когда мы пишем в bash prog X>&Y , то перед запуском происходит присваивание
file_descriptors[X] = file_descriptors[Y]
Присваивания происходят в порядке написания, через них можно сделать swap дескрипторов:

prog 3>&2 2>&1 1>&3
0
Ваша оценка: Ничего
ramok аватар

Путь начинающийся с двойного слеша

Наверное многие замечали "баг" bash/zsh в существовании "двойного root".

$ cd //
$ pwd
//
$ /bin/pwd
/

Это не ошибка, а буквальное следование стандарту POSIX (IEEE Std 1003.1-2001. 4.11 Pathname Resolution ), в котором говорится:

Цитата:

A pathname that begins with two successive slashes may be interpreted in an
implementation-defined manner, although more than two leading slashes shall be
treated as a single slash.

То есть два слеша в начале пути может быть интерпретировано в зависимости от системы. Например в cygwin таким образом можно адресовать windows share. В linux // никакого значения не имеет.

5
Ваша оценка: Ничего Рейтинг: 5 (2 голоса)
ramok аватар

Повторить символ заданное количество раз

Повторить символ заданное количество раз

$ printf 'A%.0s' {1..50}
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
$ perl -e 'print "A"x50'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
$ python -c 'print "A"*50'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
3.333335
Ваша оценка: Ничего Рейтинг: 3.3 (3 голоса)
ramok аватар

Передача файлов по сети в 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
0
Ваша оценка: Ничего
ramok аватар

Как в zsh удалить битые символические ссылки

В каталоге с активной разработкой могут накапливатся битые символические линки.
Их видно по ls -l.
Удалить их всех разом в zsh можно так

$ rm *(-@)

0
Ваша оценка: Ничего
ramok аватар

Фортунки для 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

0
Ваша оценка: Ничего
ramok аватар

Вставка последнего измененного файла в zsh

Недавно обнаружил у себя в хоткеях zsh этакое

$ bindkey
...
"^Xm" _most_recent_file
...

То есть если нажать Ctrl-x m, в командную строку вставится имя файла который менялся последним в текущей директории. Активно использую, вот несколько примеров использования:

5
Ваша оценка: Ничего Рейтинг: 5 (1 vote)
ramok аватар

Автодополнение из истории директорий в 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

Линки в тему:

0
Ваша оценка: Ничего
ramok аватар

Как сравнить два бинарных файла

К сожалению я не знаю нормального способа визуального сравнения двух бинарных файлов (что бы нормально отображалось "выпадение байта").

Тем неменее имея zsh и vim, сравнить по быстрому два бинарных файла можно так

$ vim -d =(xxd -g 1 файл1) =(xxd -g 1 файл2)

Объяснения:

  • vim -d - diff режим vim-а, он же запускается командой vimdiff
  • =(xxd -g 1 файл1) - это конструкция zsh, запускает команду внутри =(), сохраняет вывод этой команды во временный файл, и подставляет его имя вместо этой конструкции.

Линки в тему:

0
Ваша оценка: Ничего
ramok аватар

Информация о 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! Ж:-)

0
Ваша оценка: Ничего
ramok аватар

Расширеные маски файлов в 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 zshexpn
0
Ваша оценка: Ничего
FrBrGeorge аватар

Persistent 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-ам отношения не имеет.

5
Ваша оценка: Ничего Рейтинг: 5 (1 vote)
ramok аватар

Различные стили автодополнения в командной строке vim

Для тех кто хочет в командной строке vim автодополнение файлов как в bash заносим в ~/.vimrc

set wildmode=longest,list

При нажатии Tab имя файла дополнится до наибольшего совпадения и выведет список альтернатив.

Мне больше нравится автодополнение как в моем zsh

set wildmode=list:longest,full

подробности :help wildmode

5
Ваша оценка: Ничего Рейтинг: 5 (1 vote)
ramok аватар

Использование списка аргументов в bash и zsh в интерактивном режиме

Как то был совет "Вставка последнего аргумента предыдущей команды в bash и zsh." который показывает как более эффективно работать в командной строке.
Но он не поможет если вам нужен не один аргумент, а несколько. В этом совете представлен пример работы когда многим командам нужно указывать как параметр имена нескольких файлов.
Для этого используется механизм передачи параметров, который позволяет ссылаться на параметры с помощью переменно $@.

Задача: создать два скрипта, дать им права и добавить их в cvs репозиторий.

ramok аватар

Алиас для показа самых больших файлов и директорий в текущей директории

"Резиновый винчестер это не игрушка, это мечта" Ж:-)
Как всегда не хватает места, и при поиске чего бы такого удалить может помочь алиас который показывает файлы и директории которые занимают больше мегабайта.

для 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.

Пример использования:

3
Ваша оценка: Ничего Рейтинг: 3 (4 голоса)
FrBrGeorge аватар

Настройка функциональных клавиш в ZSH

Как единообразно задействовать функциональные клавиши в zsh на различных терминалах

5
Ваша оценка: Ничего Рейтинг: 5 (1 vote)
ia аватар

выполнение команды в zsh в зависимости от синтаксиса введённой строки

Бывает так, что надоедает дописывать к началу скопированной в терминал, к примеру, из браузера, ссылки, саму команду, которая должна эту ссылку обработать. Например, вот так (где | - текущее положение курсора):

Если Вам это знакомо, то Вы понимаете, о чём я. Причём речь не обязательно о git:// для git clone; это может быть lp: или bzr:// для bzr branch, http:// - для wget или aria2c, file:/// - для cd ну и т.д. и т.п. - вариантов множество и примеры использования могут зависеть от того, с какими видами пар ссылка/действие приходится работать. Конечно, можно настроить короткие алиасы для команд, но можно и пойти чуть дальше - можно настроить, что же должен выполнить zsh в зависимости от синтаксиса введённой строки. Для этого нужно отредактировать .zshrc файл, добавив туда функцию precmd (чуть подробнее про precmd можно прочитать в комментариях к коду в этом совете - http://linsovet.com/content/настройка-приглашений-zsh) примерно следующего содержания:

0
Ваша оценка: Ничего