Использование UNIX: Часть 7. Работа с командной строкой

Как расширить словарь используемых UNIX-команд

UNIX(R) поддерживает огромное количество команд. Но нет необходимости знать их все. В этой статье рассмотрены комбинации из различных команд для командной строки.

Мартин Стрейчер, главный редактор, Linux Magazine

Мартин Стрейчер (Martin Streicher) -- главный редактор журнала Linux Magazine. Он имеет степень магистра компьютерных наук Университета Пардью (Purdue University) и с 1982 занимается программированием на языках Pascal, C, Perl, Java и (с недавнего времени) Ruby в UNIX-подобных операционных системах.



05.03.2008

В путешествии по зарубежным странам, жители которых говорят на местных языках и диалектах, туристу может понадобиться знание некоторых основных фраз, например, "Сколько это стоит?", "Что это за мясо?" и "Где ванная комната?". Знание таких простых фраз гарантирует, что вы не переплатите за сандвич из змеи, который заказали, и сможете найти туалет.

UNIX® тоже имеет свой собственный диалект, и в предыдущих шести статьях из цикла "Использование UNIX" мы дали краткий курс по синтаксису команд для командной строки. В этой статье мы изучим несколько полезных фраз, которые позволят легко общаться с юниксоидами.

Введение

Предыдущие статьи цикла "Использование UNIX" (см. раздел Ресурсы) рассматривали команду find - бесценную утилиту для просмотра и обработки файлов или даже файловой системы UNIX целиком. Например, я часто использую find в комбинации с grep или Perl для обработки большого количества файлов. Если необходимо узнать, в какой части программного кода определена переменная или константа, то нужно использовать эту команду:

$ find /path/to/src  -type f | xargs grep -H -I -i -n string

Информацией, которая станет результатом работы этой команды, будет список имен файлов, содержащих строку string , включая номер строки, в которой было обнаружено вхождение искомого образца текста. Опции -H и -n добавляют к каждому совпадению имя файла, в котором оно было обнаружено, и номер строки, где было обнаружено, соответственно. Опция -i отвечает за игнорирование регистра символов. -I (заглавная I) отвечает за пропуск двоичных файлов.

Утилита xargs выполняет последовательный запуск заданной пользователем команды - в этом случае grep - со всеми параметрами, переданными на вход команде. Предположим, что каталог /path/to/src содержит файлы a, b, и c, применение find с xargs является эквивалентом последовательности команд ниже:

grep -H -I -i -n string a
grep -H -I -i -n string b
grep -H -I -i -n string c

Фактически, поиск по набору файлов настолько стандартен, что grep имеет свою собственную опцию для рекурсии по иерархии файловой системы. Используйте -d recurse или аналогичную -R, или -r. Например, рассмотрим такую команду:

$ grep -H -I -i -n -R string/path/to/src

Эта команда приводит к таким же результатам, как и find/xargs. Множество утилит в UNIX для работы с файлами содержат опции для рекурсии. ls -R рекурсивно перечисляет содержимое иерархии каталогов. chmod, chgrp, и chown используют опцию -R для наложения режимов доступа, изменений групп-владельцев и владельцев для каталогов в иерархии файловой системы. Будьте осторожны при использовании chmod -R. Пользователь может случайно испортить каталог, если удалит его исполняемые биты, например, при помощи команды chmod -R a-x, поэтому лучше применить команду find . -type f | xargs chmod a-x.

Но когда следует использовать find/xargs и в каком случае следует использовать grep? Для задания критериев используйте find. Команда find имеет много опций, которые позволяют выбирать файлы, удовлетворяющие специфическим требованиям, например, "все обычные файлы, которые были модифицированы после полуночи и принадлежат Джо". В других случаях нужно использовать grep -R.

Есть и другая утилита, которая может быть даже более удобна и работает быстрее, чем find. Если нужно найти файл по имени, то лучше использовать locate вместо find -name. Команда locate периодически (как настроит системный администратор) каталогизирует каждый файл в компьютере и создает базу данных имен файлов и путей к ним. Когда запускается locate, то она сканирует свою базу данных, пытаясь найти совпадение.

Например, запуск команды locate '*.1' приводит к выводу всех файлов и каталогов, чьи имена заканчиваются на .1. Первый символ "звездочка" означает любое совпадение. Для удобства команда locate fish идентична locate '*fish*'.


Немного работе с файлами

Множество утилит UNIX модифицируют файлы. В большинстве случаев измененное содержимое файла отправляется на стандартный поток вывода, где уже можно использовать операторы перенаправления для дальнейшей пересылки результатов и их обработки (каналы -- |) или сохранить полученные результаты (используя операторы > или >>).

Другие утилиты, обычно те, которые работают одновременно с большим количеством файлов одновременно, могут сохранять исходный файл нетронутым, создавать новый файл и записывать в него измененное содержимое исходного файла. Например, можно использовать Perl прямо в командной строке для обработки файла. Команда:

$ perl -i.bak -pe 's/\bdollar(s?)/buck\1/g' file.txt

заменяет слово dollar на buck и dollars на bucks. Команда perl -i сохраняет изменения в файле file.txt ; perl -i.bak делает копию исходного файла и добавляет к его названию копии .bak для отличия от новой, измененной версии этого файла. Команда:

perl -i.bak -pe 's/\bdollar(s?)/buck\1/g' *

создаст резервную копию каждого файла в текущем каталоге. Предположим, что имеются файл file1.txt, file2.txt, и file3.txt, в дальнейшем эти файлы будут называться file1.txt.bak, file2.txt.bak и file3.txt.bak. В случае ошибки можно легко восстановить файлы.

Если пользователь сделал ошибку и необходимо восстановить исходные файлы, то нужно просто ввести:

mv file1.txt.bak file1.txt

Но как быть, если необходимо переименовать сотни файлов? Нет нужды писать сотни отдельных команд на переименование mv. Вместо этого используйте следующую команду:

foreach file in (*.txt)
do
  mv $file.bak $file
done

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

$ rename 's/\.bak$//' *.bak

решает ту же задачу. Регулярное выражение s/\.bak$// отрезает .bak от каждого названия файла, указанного в командной строке - в этом примере указан символ "звездочка" (*) для обработки каждого файла - и использует полученное укороченное имя как имя для конечного файла.

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

$ ls
RenT.txt  bEErMoNey.txt  gASmoNey.TXt

Код с foreach, приведенный выше, не может решить эту проблему, потому что имена файлов очень сильно отличаются. А rename может очень даже просто справиться с этой задачей:

$ rename 'y/A-Z/a-z/' *

Оператор y в регулярном выражении y/A-Z/a-z/ используется для преобразования (translation) записей. Для преобразования необходимо два списка: список исходных символов и список символов, на которые надо заменить исходные символы. Если эти два списка одинакового размера, каждая буква из списка исходных символов замещается соответствующей буквой из списка символов на замену. Иначе говоря, в данном примере каждая заглавная буква A замещается строчной буквой a, B - на b и так далее. Строчные буквы, что уже были в тексте, остаются без изменений.

Если нужно посмотреть, как работает команда rename, то добавьте опцию -n. Эта опция показывает действия команды без совершения каких-либо реальных изменений в файлах, над которыми выполняются операции:

$ rename -n 'y/A-Z/a-z/' *
RenT.txt renamed as rent.txt
bEErMoNey.txt renamed as beermoney.txt
gASmoNey.TXt renamed as gasmoney.txt
$ rename 'y/A-Z/a-z/' *
$ ls
beermoney.txt  gasmoney.txt  rent.txt

Примечание. На UNIX-системах имена файлов чувствительны к регистру букв. Каталог может содержать Aa.Txt и aA.txT. Если написать, как было показано выше, правило для переименования файлов, которое конвертирует названия файлов в нижний регистр, то оно может повлечь за собой конфликт одинаковых файловых имен. Что делает rename в этом случае? Давайте посмотрим:

$ rename -n 'y/A-Z/a-z/' *
Aa.Txt renamed as aa.txt
aA.txT renamed as aa.txt
$ rename 'y/A-Z/a-z/' *
aA.txT not renamed: aa.txt already exists
$ ls
aA.txT  aa.txt

Если нужно удалять повторяющиеся файлы по ходу процесса переименования, то добавьте флаг -f. В этом примере результатом будет один файл aa.txt. А какой из двух этих файлов является первым? Ввиду того, что rename работает с файлами в алфавитном порядке, последним будет переименован файл aA.txT. Зачем использовать флаг -f? Если два файла идентичны во всем, кроме своих названий, команда rename -f удалит дубликат.


Как случайно не удалить нужный файл

Значительная часть работы с UNIX связана с операциями по управлению файлами. В любом компьютере UNIX имеется множество конфигурационных файлов, да и у любого пользователя наверняка имеется много своих файлов с данными. Иногда можно случайно удалить или перезаписать важный файл. Оболочка shell и несколько утилит для управления файлами могут помочь избежать таких ситуаций.

Введите следующие команды в ответ на приглашение shell (данный пример относится к оболочке bash, но похожие команды существуют в zsh и других оболочках).

$ alias mv=mv -i
$ alias rm=rm -i
$ set -o noclobber

Первые две команды заменяют mv на mv -i и rm на rm -i, соответственно в строке команды. При помощи интерактивного режима осуществляется подтверждение выбора нужного действия.

Третья команда добавляет дополнительный, хотя и очень простой уровень безопасности в саму оболочку. Если активированн режимом noclobber, то уже нельзя случайно перезаписать файл, используя оператор >:

$ ls
secret.txt
$ cat > secret.txt
bash: secret.txt: cannot overwrite existing file

Для отключения режима noclobber нужно ввести:

set +o noclobber

Также можно осуществить принудительную перезапись в любое время при помощи оператора переадресации >| (символ "больше-чем" (greater-than), за которым следует вертикальная черта).

$ cat secret.txt
I love green eggs and ham.
$ echo "No more secrets" >| secret.txt
$ cat secret.txt
No more secrets

Несколько полезных команд в UNIX

Ниже представлено несколько полезных команд:

mkdir -p выполняет создание иерархии каталогов. С опцией -pmkdir создает по указанному адресу каталог и вложенный каталог:

$ mkdir -p make/many/directories/at/once
$ ls -R
./make:
many

./make/many:
directories

./make/many/directories:
at

./make/many/directories/at:
once

./make/many/directories/at/once:

Если нужно узнать, когда в следующий раз вам выдадут зарплату, введите cal. Без аргументов cal выведет календарь на текущий месяц. Команда cal -3 календарь на текущий, предыдущий и следующий месяц, а cal 06 2009 покажет июнь 2009 года.

$ cal

   November 2006
Su Mo Tu We Th Fr Sa
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
$ cal 06 2009

     June 2009
Su Mo Tu We Th Fr Sa
    1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

Из-за того что UNIX имеет много команд, просто физически невозможно запомнить все опции для всех команд. Временами трудно вспомнить даже название утилиты.

В затруднении пользуйтесь справочной системой man. Введите man man, например, чтобы узнать, как пользоваться самой системой помощи man. Для вывода справки по командам rm и mv нужно ввести для man rm и man mv соответственно. И если известно название нужной команды, то используйте команду man -k для поиска в справочной системе man по заданной теме.

$ man -k cron
cron (8)             - daemon to execute scheduled commands (Vixie Cron)
crontab (1)          - maintain crontab files for individual users (V3)
crontab (5)          - tables for driving cron
dh_installcron (1)   - install cron scripts into etc/cron.*

Здесь man предоставил краткое описание утилит и понятий, в чье название входит слово cron. Среди предоставленных описаний есть и искомая утилита cron для запуска процессов по расписанию.

А зачем нужны числа в таблице с результатами запроса по справке man? Каждое число ссылается на раздел online-руководства UNIX. Раздел 1 зарезервирован для всех команд, которые UNIX-пользователь может запустить из оболочки. Раздел 5 описывает форматы файлов. Раздел 8 каталогизирует команды системного администрирования. Другие разделы описывают команды системного вызова (2), вызовы библиотек (3) и прочее.

В результате работы команд обычно выдается какая-то информация. Большинство команд использует стандартный поток вывода для результатов своей работы. Другие утилиты используют стандартный поток вывода и стандартный поток вывода ошибки для отображения процесса выполнения команды (но не итоговых результатов работы) и сообщений об ошибках. Обычно не требуется использовать эти возможности отображения информации, поскольку они мешают работать с командной строкой, поэтому следует перенаправить поток вывода в "черную дыру" UNIX (bit bucket), /dev/null. Биты записываются туда, но из нее ничего не выходит наружу.

$ ls
secret.txt
$ cat secret.txt
I am the Walrus.
$ cat secret.txt > /dev/null
$ cat socrates.txt > /dev/null
cat: socrates.txt: No such file or directory
$ cat socrates.txt >& /dev/null
$ echo Done.
Done.

Если перенаправить стандартный поток вывода утилиты cat на /dev/null, то ничего не выведется, поскольку все биты были записаны в "черную дыру". Однако если пользователь сделает ошибку, то сообщение об ошибке, которое записывается в специальный поток вывода ошибок, все же будет отображено. Если нужно игнорировать всю выводимую информацию, то используется оператор >& для перенаправления stdout и stderr в "черную дыру".

Также можно использовать /dev/null в качестве файла нулевой длины для удаления содержимого других файлов и создания новых, пустых файлов:

$ cat secret.txt
Anakin Skywalker is Darth Vader.
$ cp /dev/null secret.txt
$ cat secret.txt
$ echo "The moon is made of cheese!" > secret.txt
$ cat secret.txt
The moon is made of cheese!
$ cat /dev/null > secret.txt
$ cat secret.txt
$ cp /dev/null newsecret.txt
$ cat newsecret.txt
$ echo Done.
Done.

Кстати, при работе с UNIX на компьютерах очень удобна команда open в окне терминала. Например, если текущий рабочий каталог содержит файл poodle.jpg, команда open poodle.jpg запустит программу Preview ( встроенную утилиту просмотра изображений Mac OS X), которая и выведет картинку. Mac OS X open является связующим звеном между командной строкой и многооконной средой Macintosh, и это работает намного быстрее, чем вызов Finder.


Заключение

В этой статье достаточно кратко изложено много информации, позволяющей и дальше исследовать UNIX.

Следующая статья цикла "Использование UNIX" будет посвящена контролю процессов, регулярным выражениям и инсталляции загруженных из Интернета утилит.

Ресурсы

Научиться

Получить продукты и технологии

  • IBM trial software: ознакомительные версии программного обеспечения для разработчиков, которые можно загрузить прямо со страницы сообщества developerWorks.(EN)

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=AIX и UNIX
ArticleID=293293
ArticleTitle=Использование UNIX: Часть 7. Работа с командной строкой
publish-date=03052008