Удобство работы в консоли

Материал из Belgorod Linux User Group - Белгород

Версия от 09:16, 1 апреля 2015; 107 (обсуждение | вклад)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Содержание

Кому это надо?

Вы решили изучить GNU linux, или просто устали от графической оболочки, или часто пользуетесь консолью и считаете что это не удобно - результатом может оказаться всякие графические "недо" конфигурилки которые делают не то что ожидается - и следствие мысли что offtopic лучше а linux сыроват, а может быть просто расширить кругозор. Если это про Вас, тогда приступим ;)

От простого к сложному

Что мы видим в консоли в первую очередь? Мой shell: bash, zsh, csh, ksh

Приглашение командной строки

bash

Строка приглашения в bash

zsh

Удобство работы в zsh

csh

ksh

Простые радости

Установка времени и даты

man date
date --set 4/13/2004 
date --set 14:46:27

Чтение файла с автообновлением

tail -f <file>

очень удобно смотреть логи:

tail -f /var/log/message

grep с цветом

Попробовав раз, пользуюсь до сих пор

grep --color=auto

пример

grep --color=auto -R 'adm:' /etc
ps ax | grep --color=auto root

чтобы не вбивать вечно color=auto можно сделать следующее для bash:

alias grep='grep --color=auto'

или записать эту строчку в ~/.bashrc or ~/.bash_profile

копирование файлов

строка прогресса

Очень удобно когда ты видишь сколько осталось копироваться и сколько скопировалось: для пропатченных версий coreutils'ов!

cp -g <file> <destination>
cp -gr <dir> <destination>
cp -g /var/log/messages ~/

Еще один вариант(для всех):

scp <file> localhost:<destination>

по сети

Для этого на <host> должен присутствовать sshd сервер.

scp <file> <user>@<host>:<destination>
scp -r <dir> <user>@<host>:<destination>

Или подмонтировать его по nfs

просмотр дисков и разделов

fdisk -l

вычисления в консоли

если у вас отсутствует пакет bc

whereis bc

то можете производить простые арифметические операции следующим способом

echo $((500+312*23))

если bc есть можно

echo "500+312*23" | bc

или запустить

bc 

и в интерактивном режиме считать используя команды и сокращения bc( описание использования bc в интерактивном режиме на английском )

Vim

mc или ...

Многие пользователи просто не понимают как жить без mc (читаем файловый менеджер). Это же - я не увижу, куда копируется!!! и что происходит??? и как с одной директории в другую переместить файл?? а в архивы заходить????! и прочее и прочее ... Давайте для начала не пугаться, и не отказываться сразу от файлменеджеров - и после сидеть показывая "я же говорил что так дольше и хуже" ... лучше посмотрим, какие есть альтернативы функциональности файлового менеджера консольными утилитами.

Примечание: кому то покажется это бредом ведь "mc же консольный?!", что тут скажешь? Да, фактически да, но есть ли смысл "уходить" с иксов в якобы консоль, чтобы на самом деле сидеть и все делать в mc???

Архивы

Для навигации внутри архивов можно использовать пакет avfs Это fuse-модуль, который позволяет "прозрачно" работать с архивами.

Для этого ставим вашим пакетным менеджером avfs (скорее всего притянется и fuse). Затем создаем директорию ~/.avfs

mkdir ~/.avfs

И монтирует ее:

mountavfs

Теперь там же у вас будет продублирована ваша файловая система, только через avfs, и можно будет "заходить" в архивы как в директории дописывая знак # в конец имени. И следовательно выполнять любые операции с файлами внутри них:

cd ~/.avfs/home/user/tmp/
cd archive.zip\#

bash-completion

Что такое bash-completion? Давайте сначала его поставим\настроим, и посмотрим что это. для установки (на моем любимо дистрибутиве :)) ) нужно:

emerge bash-completion

для gentoo также нелохо было бы

emerge gentoo-bashcomp

подредактировать файл /etc/make.conf добавив в USE флаги bash-completion и пересобрать те пакеты в "мире", которые его используют:

emerge -avuN world

далее в .bashrc впихиваем строчку

echo "test -f /etc/profile.d/bash-completion && source /etc/profile.d/bash-completion" >> ~/.bashrc

и не забываем включить eselect'ом остальные

cd /usr/share/bash-completion &&  for i in `ls -1`; do eselect bashcomp enable $i; done

и "перелогиниваемся", теперь после команды

svn l<TAB>

получаем список параметров. Примеры на самом деле скажут лучше все сами за себя (попробуйте):

kill -<TAB>
kill <TAB>
killall <TAB>
vim --<TAB>
unrar <TAB>
su <TAB>
eselect <TAB>
rsync --<TAB>

И так далее.

zsh

Для продвинутых

Просмотр блокировок и занятых ресурсов и их завершение

/usr/sbin/lsof

или

lsof | grep <директория\файл\pid процесса\пользователь>

Если запускать lsof не от рута, то будут показаны файлы только от текущего пользователя. Завершить все процессы, которые работают с /home.

fuser -km /home

Учимся писать скрипты

Здесь рассматривается только bash-скрипты, все приведенные примеры могут не работать в любых других shell'ах.

Маленькое вступление

Вообще это довольно сложное занятие - грамотно написать скрипт. Естественно в заголовке должно быть #!/bin/bash и скрипт должен быть executable (chmod +x <script_filee>). Что же тут сложного? Казалось, написал

#!/bin/bash
cdrecord -sao -speed=24 dev=/dev/hdd test.iso

и все - пользуюсь, когда надо чтобы не вбивать, допустим длинную строку. Но такой скрипт скоро станет бесполезным, легко предсказуема трансформация в

cdrecord -sao -speed=24 dev=/dev/hdd $1

ну теперь вроде лучше, пишу ./my_burn /home/work/second.iso и хорошо живу но!

Вспоминаем зачем нужны скрипты? Чтобы облегчить жизнь. Для данного примера ситуация: диск записался не правильно (не читается). Это ж легко решается сверкой контрольной суммы. Ну теперь мы умные будем проверять контрольную сумму, пару раз вручную, хорошо если сразу дошли руки заскриптовать (наверно в отдельном скрипте). Все это здорово но запускать ./my_burn /home/work/second.iso && ./check_md5 /home/work/second.iso не очень удобно(можно конечно перейти в cd /home/work и ессно скрипты в PATH'е но это тоже не выход).

Понятно теперь что скрипт нужно писать сразу максимально полнофункциональным. Итак приступим.

Входные переменные

Даже в нашем скромно-тестовом примере используются входная переменная, говорить, что грамотно организованное взаимодействие скрипта "с консолью" является важной задачей надеюсь излишне.

У нас есть набор входных параметров и определенные комбинации этих параметров для скрипта, которые чаще всего и определяют его поведение. В нашем примерочном скрипте у нас один параметр - это путь к iso-файлу. То есть если параметров нету, то что должен делать скрипт? Писать что-то по умолчанию? Вываливать ошибку или еще какое действие. Сначала нужно четко определить границы функционала данного скрипта - наш скрипт будет "только писать". Это означает что наш скрипт не будет создавать iso'образы или проверять директории на вирусы или еще какой функционал. То есть параметр должен быть для начала один. И если его нет, то можно начать писать диск по умолчанию, но обязательно нужно спросить пользователя, желательно указав что сейчас будет происходить.

if [ $# -gt 1 ]; then
    echo "Usage: $0 <path_iso_file>"
    exit
fi
if [ "x$1" = "x" ]; then
    echo -n "Burn default iso - $default_iso (yes/no):"
    read answ
    test "yes" != $answ && exit
    burn $default_iso
else
    burn $1
fi

Теперь давайте разберемся, что тут делает каждая команда.

Условный оператор - if then else fi

Самая распространенная конструкция во всех языках. В bash'е имеется небольшое отличие - это fi для завершения конструкции. Синтаксис ее прост

if условие; then
   действие если условие true(для bash'a это ноль)
else
   действие если условие false(для bash'a это все что не ноль: 1,12 и т.д.)
fi

Тут ничего военного нету, только если вы хотите написать if в одну строку, то не надо забывать разделитель ';'

if условие; then действие_true; else действие_false; fi

или без else

if условие; then действие_true; fi

test или []

Для сравнений и всевозможных проверок придумана утилита test или []. То есть в первой строчке

if [ $# -gt 1 ]; then

условный оператор проверяет условие, которое формирует test. Условие звучит так: если параметров скрипта больше чем один, то( gt - Greater than).

[ "x$1" = "x" ]

Знак '=' сравнивает строки на равенство, дополнительный x неспроста. Если попытаться сравнить не определенную переменную с строкой

$tochno_netu_takoy_variable = "test"

то test ругнется:

test: =: unary operator expected

Логически получается что этой строкой мы проверяем не пусто ли $1. Можно эту проблему решить по другому (-n дает true если размер строки больше 0):

[ -n $1 ]

Также часто "численное сравнение" используется -eq (противоположность -ne)

[ $num -eq 5 ]

Более подробную информацию может подсказать man test.

Ввод и вывод

echo "Usage: $0 <path_iso_file>"

Выводит на экран строку, в которой заместо $0 подставляется имя скрипта. В bash (как и в php кстати), переменные можно использовать внутри двойных кавычек "", но внутри одинарных будет выводится $0 без подстановки переменной.

echo -n "Burn default iso - $default_iso (yes/no):"

-n здесь говорит о том что после вывода строки не нужно делать перевод строки (символ '\n'). Еще иногда используется параметр -e, который говорит echo обрабатывать каждую спец последовательность (список их можно посмотреть в man echo) в строке. Пример:

echo -e "\nblabla\n\op\n"

По умолчанию используется -E, который не обрабатывает спец посл.

read answ

Читает введенные с клавиатуры одну строку и "записывает" ее в перменную answ. Если до этого переменная не была определенна, то она становися определенна в данном блоке видимости (об этом позже). Еще у read есть очень полезная опция -t означает время(в секундах) ожидания ввода, если по истечении этого времени ввод не был закончен то выполнение read аварийно завершается (код возврата 1). И управление переходит на следующую после read команду:

read -t 4 answ && echo -e "read ok\nansw=$answ" || echo "ne uspeli"

Попробуйте разобраться в данной конструкции.

&& - аналог AND
|| - аналог OR

Функциональность и последущее использование

Хорошо, мы научились включать в скрипт параметры, читать ввод с клавиатуры и информировать пользователя о работе скрипта. Что же еще может потребоваться?

Полезные штуки

Перманентное хранение переменной

function put () {
       DIR=/tmp/
       eval "$1=$(cat /$DIR/$1.swp 2>/dev/null)" # load
       (($1$2))
       eval "echo \$$1" > /$DIR/$1.swp # save
}

Данная функция будет сохранять перемененную даже после окончания выполнения скрипта (на диск). Полезно для сохранения всяких счетчиков по крону. Использование:

put w =0
put w ++ 
put w +=3
put w (чтобы просто загрузить ее)

В коде так же будет возможно обращение к этой переменной как к обычной:

put w ++
if [ $w -gt 4 ]; then
reboot
fi
Личные инструменты