10 хороших привычек UNIX

Автор: Michael Stutz (stutz@dsl.org)

Перевод: Dimaka http://dimaka.net/pool/85

Оригинал: http://www-128.ibm.com/developerworks/aix/library/au-badunixhabits.html?ca=lnxw01GoodUnixHabits

Изучите 10 хороших привычек которые повысят эффективности использования вами командной строки и заодно избавтесь от использования неправильных шаблонов выполнения команд. Эта статья шаг за шагом ознакомит вас с хорошей
но так часто забываемой, техникой работы в командной строке. Узнайте о частых ошибках и как их исправить, и вы поймете почему к этим привычкам UNIX стоит приучиться.

Вступление



Если вы много времени работаете с системой, то у вас уже должны заложиться некоторые шаблоны использования команд. Иногда, вы просто выполняете задачу и не ищете способа “как это можно сделать проще” (как я, например), в результате
вы получаете плохую практику и становитесь “неуклюжим” в выполнении задач. Лучший способ исправить эти недостатки - это сознательно подойти к изучению новых привычек, которые будут противодействовать старым. Здесь вам предлагают
10 привычек командной строки UNIX - которые помогут вам исправить все ваши ошибки и сделать вас более производительными при работе с командной строкой. Каждая привычка более детально описана в списке полезных привычек.
Изучите 10 хороших привычек

10 хороших привычек, которые следует заучить:



  1. Создавайте деревья каталогов одной командой.
  2. Распаковывайте архив в нужную директорию, не копируя его туда преждевременно.
  3. Обьеденяйте ваши команди с операторами.
  4. Осторожно цитируйте переменные.
  5. Используйте escape-последовательности при работе с длинными вводами команд.
  6. Обьеденяйте команды в список.
  7. Используйте xargs как фильтр для find.
  8. Узнайте, когда подсчет строк лучше делать с помощью grep, а когда с wc -l.
  9. Обьеденяем нужные нам елементы в результате, а не выводим полностью строку.
  10. Прекратите перенаправлять все через cat.

Создавайте деревья каталогов одной командой.



Урок 1: Пример плохой привычки №1: Создание дерева каталогов по отдельности

~ $ mkdir tmp
~ $ cd tmp
~/tmp $ mkdir a
~/tmp $ cd a
~/tmp/a $ mkdir b
~/tmp/a $ cd b
~/tmp/a/b/ $ mkdir c
~/tmp/a/b/ $ cd c
~/tmp/a/b/c $

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

Урок 2. Пример хорошей привычки №1. Создание дерева каталогов с помощью одной команды

~ $ mkdir -p tmp/a/b/c

Вы можете использовать эту опцию, чтобы создавать комплексные директории, это очень удобно использовать в скриптах, а не только в простой иерархии. Например:
Урок 3. Другой пример хорошей привычки №1. Создание комплексных директорий

~ $ mkdir -p project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}

В прошлом mkdir не поддерживало эту опцию, но теперь это не так в большинстве систем. IBM, AIX®, mkdir, GNU mkdir, которые соответствуют единой спецификации UNIX - поддерживают теперь эту опцию.

В некоторых же системах до сих пор этой опции нету, и там используется скрипт mkdirhier, который являеться оболочкой для mkdir и выполняет такие же функции:

~ $ mkdirhier project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}

Распаковывайте архив в нужную директорию, не копируя его туда преждевременно



Также плохим стилем являеться перемещение архива в директорию, потому что вы хотите его распаковать в неё. Не надо этого делать. Вы можете распаковать .tar архив в любую директорию - с помощью опции -C
Используйте опцию -C, чтобы указать директорию куда распаковать архив:

Урок 4. Пример хорошей привычки №2: Использование опции -C для распаковки .tar архива

~ $ tar xvf -C tmp/a/b/c newarc.tar.gz

Это намного удобней, чем поместить архив в нужной директории, потом перейти в неё и только потом начать распаковывать архив.

Обьеденяйте ваши команды с операторами



Вы должны знать, что в командной строке можно обьеденять команды в одной строке разделяя их точкой с запятой (Eye-wink. Точка с запятой является оператором командной строки, это полезно для обьеденения нескольких дискретных команд в одной строке,
но это не работает везде. Допустим, вы используете точку с запятой, чтобы обьеденить 2 команды, правильное выполнение второй - зависит от успешного выполнения первой. Если первая команда не завершилась, как вы того ожидали - то вторая продолжает работать,
что приводит к ошибке. Вместо этого, используйте более надлежащие операторы (некоторые из них описаны в этой статье). Пока ваша командная строка их поддерживает - это стоит того, чтобы стать полезной привычкой по их использованию.

Выполнить команду, только если другая возвращает нулевой статус при завершении.



Используйте оператор && для обьеденения 2-х команд, с условием, что вторая запускаеться только в случае если первая возвращает нулевой статус при завершении. Другими словами - если первая команда выполнилась успешно - то запускается вторая. Если первая завершилась неудачно,
то вторая вообще не выполняется. Например:

Урок 5. Пример хорошей привычки №3: Обьеденение команд с помощью операторов

~ $ cd tmp/a/b/c && tar xvf ~/archive.tar

В этом примере, содержимое архива, будет распаковано в директорию ~/tmp/a/b/c, если она существует. Если это не так, то команда tar не будет выполнена и ничего не распакуется.

Выполнить команду, только если другая возвращает ненулевой статус при завершении.



Аналогичным образом, оператор || разделяет 2 команды и запускает вторую, только если первая возвращает ненулевой статус. Другими словами - если первая завершилась успешно, то вторая не запускается. Если же первая завершилась неудачно, то вторая команда будет выполнена. Этот оператор
часто исользуется для проверки наличия директорий/файлов и создания последних, если они отсутствуют:

Урок 6. Другой пример хорошей привычки №3: Обьеденение команд с помощью операторов

~ $ cd tmp/a/b/c || mkdir -p tmp/a/b/c

Создаст иерархию tmp/a/b/c, если такой нету.

Вы также можете обьеденять операторы описанные в этом разделе. Каждый работает с последней запущенной командой:

Урок 7. Обьедененный пример хорошей привычки №3: Обьеденение команд с помощью операторов

~ $ cd tmp/a/b/c || mkdir -p tmp/a/b/c && tar xvf -C tmp/a/b/c ~/archive.tar

Осторожно цитируйте переменные



Всегда будьте осторожны с расширениями командной строки и именами переменных. Неплохо бы заключать значения переменных в кавычки (”"), если только нету причин чтобы этого не делать.
Точно так же если вы используете переменную с буквенно-цифровым текст, вы должны закрывать её в фигурные скобки ({}) чтобы оградить переменную от остального текста.
В противном случае оболочка интерпретирует остальной текст как часть имени переменной и скорее всего результат будет нулевым. В уроке 8 показаны цитированные и не цитированные переменные и их результаты.

Урок 8. Пример хорошей привычки №4: Цитированные (и не цитированные) переменные

~ $ ls tmp/
a b
~ $ VAR="tmp/*"
~ $ echo $VAR
tmp/a tmp/b
~ $ echo "$VAR"
tmp/*
~ $ echo $VARa

~ $ echo "$VARa"

~ $ echo "${VAR}a"
tmp/*a
~ $ echo ${VAR}a
tmp/a
~ $

Используйте escape-последовательности при работе с длинными вводами команд



Вы уже наверное видели примеры кода, в которых бэкслэш (\) переносит длинные строки в следующий ряд и все что вы видите в нескольких рядах - это на самом деле одна длинная строка. Это решение применяется не так уж и часто, но в некоторых
случаях, его применение очень полезно, например когда ваш терминал не поддерживает правильно многострочность или ваша командная строка меньше чем обычно (например когда в строке приветствия у вас длинный путь к каталогу).
Использование бэкслеша поможет представить длинные вводы команда - в более понятном смысловом виде, как на примере:

Урок 9. Пример хорошей привычки №5: Использование бэкслэша при длинном вводе команд

~ $ cd tmp/a/b/c || \
> mkdir -p tmp/a/b/c && \
> tar xvf -C tmp/a/b/c ~/archive.tar

Кроме того, следующий пример так же работает:

Урок 10. Альтернативный пример хорошей привычки №5: Использование бэкслэша при длинном вводе команд

~ $ cd tmp/a/b/c \
> || \
> mkdir -p tmp/a/b/c \
> && \
> tar xvf -C tmp/a/b/c ~/archive.tar

Оболочка всегда видит такое как одну строку, так как выравнивает строчки разделенные бэкслэшами и специальными пробелами.

Примечание: Во многих терминалах, когда вы нажимаете стрелку вверх - то все многострочные записи перестраиваются в одну длинную строку.

Обьеденяйте команды в список



Во многих оболочках можно обьеденять команды в списки и выполнять их, так чтобы видеть общий результат (вывод) или же направлять его в нужное вам место. Делать это можно
запуская список команд в первичной или вторичной оболочках.

Запуск списка команд во вторичной оболочке

Закрывайте список команд в одной групе скобками. Это запускает команды в новой вторичной оболочке и позволяет собирать общие результаты, как показано на примере:

Урок 11. Пример хорошей привычки №6: Запуск списка команд во вторичнй оболочке

~ $ ( cd tmp/a/b/c/ || mkdir -p tmp/a/b/c && \
> VAR=$PWD; cd ~; tar xvf -C $VAR archive.tar ) \
> | mailx admin -S "Archive contents"

В этом примере, содержимое архива распаковываеться в каталог tmp/a/b/c/ в то время как результат сгрупированых команд, включая список распакованых файлов, отправляются на почту администратору.
Использование вторичной оболочки предпочтительно в том случае, если вы задаете какие-то переменные в списке ваших команд и не хотите чтобы они были применены к первичной оболочке.

Запуск списка команд в первичной оболочке

Используйте фигурные скобки ({}) для списка команд, чтобы запустить его в первичной оболочке. Убедитесь, что поставили пробелы между скобками и командами, иначе оболочка неправильно будет интепритировать скобки.
Также убедитесь, что последняя команда в вашем списке заканчивается точкой с запятой (Eye-wink, так как в следующем примере:

Урок 12. Другой пример использывания хорошей привычки №6: Запуск списка команд в первичной оболочке

~ $ { cp ${VAR}a . && chown -R guest.guest a && \
> tar cvf newarchive.tar a; } | mailx admin -S "New archive"

Используйте xargs как фильтр для find



Используйте xargs как фильтр для результатов команды find. Общий принцип перспективы find состоит в том, чтобы вывести список файлов, которые соответствуют какому-то критерию. Далее этот список перенаправляется на обработку к xargs который
с помощью разных полезных команд работает со списком файлов как с аргументами, вот пример:

Урок 13. Пример классического использования xargs

~ $ find some-file-criteria some-file-path | \
> xargs some-great-command-that-needs-filename-arguments

Однако, не думайте, что xargs это всего лишь помощник для find… это один из тех недостающих инструментов, который будет часто использоваться вами для решения последующих задач. Просто помните, это должно войти в привычку.

Создание списка разделенного пробелами
В этом случае, xargs фильтрует входящий список (где каждый член находиться на отдельной строке) и выстраивает все даные разделенные пробелами строку:

Урок 14. Пример вывода xargs

~ $ xargs
a
b
c
Control-D
a b c
~ $

Вы можете перенаправлять вывод любой команды в xargs, чтобы получить список аргументов для других команд, которые понимают имена файлов как аргументы, как в следующем примере:
Урок 15. Пример использования xargs

~/tmp $ ls -1 | xargs
December_Report.pdf README a archive.tar mkdirhier.sh
~/tmp $ ls -1 | xargs file
December_Report.pdf: PDF document, version 1.3
README: ASCII text
a: directory
archive.tar: POSIX tar archive
mkdirhier.sh: Bourne shell script text executable
~/tmp $

xargs полезен не только для работы с именами файлов, так же вы можете использовать его чтобы выстраивать нужный текст в одну строку:
Урок 16. Пример хорошей привычки №7: Использование xargs для выстраивания текста в одну строку

~/tmp $ ls -l | xargs
-rw-r--r-- 7 joe joe 12043 Jan 27 20:36 December_Report.pdf -rw-r--r-- 1 \
root root 238 Dec 03 08:19 README drwxr-xr-x 38 joe joe 354082 Nov 02 \
16:07 a -rw-r--r-- 3 joe joe 5096 Dec 14 14:26 archive.tar -rwxr-xr-x 1 \
joe joe 3239 Sep 30 12:40 mkdirhier.sh
~/tmp $

Будьте осторожными используя xargs
Проблемы при использовании xargs встречаються редко. Но, по умолчанию последняя строка файла заканчиваеться подчеркиванием (_); если этот символ отправлен как одиночный входящий аргумент, то все что идет после него - игнорируется. Во
избежание подобных ситуаций, используйте флаг -e, который без аргументов, отключает конце файла полностью.

Узнайте, когда подсчет строк лучше делать с помощью grep, а когда с wc -l



Избегайте перенаправления grep в wc -l для того чтобы подсчитать коливчество строк в выводе. grep с опцией -c показывает количество строк, которые соответствуют укзаному порядку и в целом быстрее чем перенаправление вывод в wc, например:

Урок 17. Пример хорошей привычки №8: Подсчет строк с и без grep

~ $ time grep and tmp/a/longfile.txt | wc -l
2811

real 0m0.097s
user 0m0.006s
sys 0m0.032s
~ $ time grep -c and tmp/a/longfile.txt
2811

real 0m0.013s
user 0m0.006s
sys 0m0.005s
~ $

В добавок к скоростному фактору, опция -c еще и лучший способ для подсчета. В случаях с несколькими файлами grep с опцией -c раздельно показывает количество для каждого файла, в то время как перенаправление в wc - показывает общее количество
со всех файлов.

Однако независимо от скоростных соображений, этот пример показывает другие ошибки, которые следует избегать. Эти методы подсчета, показывают только количество строк которые содержат некое соотвествие структуры - и если это то что вам нужно, тогда чудесно. Но в случаях, когда несколько строк имею какую-то определенную структуру, эти методы не покажут верно число строк. В таких
случаях уже надо использовать wc. Сперва запустите команду grep с опцией -o, если ваша версия это поддерживает. Эта опция выводит по одному результату со схожей структурой на строке, а не саму строку. Но эту опцию нельзя использовать совместно с -c, так что используйте wc -l для подсчета строк, например:
Урок 18. Пример хорошей привычки №8: Подсчет строк с определенной структурой при использовании grep

~ $ grep -o and tmp/a/longfile.txt | wc -l
3402
~ $

В таком случае обращение к wc немного быстрее, чем повторный вызов grep по фиктивной схеме для определения и посчета каждой строки (как grep -c).

Обьеденяем нужные нам елементы в результате, а не выводим полностью строку


Такой инструмент как awk предпочтительней grep, в тех случаях, когда нужно выделить лишь елементы с заданым шаблоном (в выводе команды), а не все схожие строки.
Следующий простой пример, показывает как вывести список файлов, измененных в Декабре(December):

Урок 19. Пример плохой привычки №9: Использование grep для того чтобы найти поля с нужными елементами:

~/tmp $ ls -l /tmp/a/b/c | grep Dec
-rw-r--r-- 7 joe joe 12043 Jan 27 20:36 December_Report.pdf
-rw-r--r-- 1 root root 238 Dec 03 08:19 README
-rw-r--r-- 3 joe joe 5096 Dec 14 14:26 archive.tar
~/tmp $

В этом примере grep фильтрует строки по наличию елемента Dec как в модификаторе даты, так и в именах файлов. И такой файл как December_Report.pdf попадает под заданый критерий, не смотря на то что быз изменен в Январе(January). Скорее всего это не то что вам нужно.
Для нахождения заданных елементов в определенных полях, лучше использовать awk, оператор которого ищет елементы в заданных полях, как в следующем примере:

Урок 20. Пример хорошей привычки №9: Использование awk, для нахождения шаблонов в заданных полях

~/tmp $ ls -l | awk '$6 == "Dec"'
-rw-r--r-- 3 joe joe 5096 Dec 14 14:26 archive.tar
-rw-r--r-- 1 root root 238 Dec 03 08:19 README
~/tmp $

Смотрите документацию, чтобы найти больше информации по использованию awk.

Прекратите перенаправлять все через cat



Основной ошибкой, при использовании команды grep - являеться перенаправление её через cat при поиске по содержимому одного файла. Это полностью необязательно, так как grep воспринимает имя файла как аргумент.
Этот пример показывает, что вам вобще не надо использовать cat в таких ситуациях:

Урок 21. Пример плохой и хорошей привычки №10: Использование grep c и без cat

~ $ time cat tmp/a/longfile.txt | grep and
2811

real 0m0.015s
user 0m0.003s
sys 0m0.013s
~ $ time grep and tmp/a/longfile.txt
2811

real 0m0.010s
user 0m0.006s
sys 0m0.004s
~ $

Эта ошибка повторяется со многими инструментами. К использованию cat нужно прибегать, когда вы хотите использовать фильтр.

Заключение: “Пожимаем руки”



Проверка вашего использования командной строки на наличие плохих привычек, это очень хорошо. Так как плохие привычки вас замедляют и иногда приводят к неожиданным ошибкам. В этой статье было представлено 10 новых привычек, которые помогут вам
перебороть старые, которые были насыщены стандартными ошибками.

Перенимание этих хороших привычек, это шаг вперед по развитию навыков работы с командной строкой UNIX.
05.09.2008 - 01:17
Элементы пишется через букву "э". Исправьте пожалуйста. (http://www.gramota.ru/slovari/dic/)
RSS-материал RSS-материал