Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Фундаментальные основы Linux. Часть III. Раскрытие команд командной оболочкой

Оригинал: Linux Fundamentals
Автор: Paul Cobbaut
Дата публикации: 16 октября 2014 г.
Перевод: А.Панин
Дата перевода: 13 декабря 2014 г.

Глава 10. Команды и аргументы

В данной главе вашему вниманию представляется обзор механизма раскрытия команд командной оболочки (shell expansion), созданный в ходе подробного рассмотрения методик обработки команд и аргументов. Понимание принципа работы механизма раскрытия команд командной оболочки является важным ввиду того, что многие команды в вашей системе Linux подвергаются обработке и с высокой вероятностью последующей модификации средствами командной оболочки перед исполнением.

Интерфейс командной строки системы или командная оболочка, используемая в большинстве систем Linux, носит имя bash, которое расшифровывается как Bourne again shell (название "Born again shell" - "возрожденная командная оболочка" было изменено с целью упоминания автора оригинальной командной оболочки sh Стивена Борна). Командная оболочка bash реализует возможности командных оболочек sh (оригинальная командная оболочка Стивена Борна), csh (командная оболочка Билла Джоя с поддержкой сценариев, синтаксис которых основан на синтаксисе языка программирования C), а также ksh (командная оболочка Дэвида Корна).

В данной главе для демонстрации возможностей командной оболочки будет периодически использоваться команда echo. Команда echo является достаточно простой командой: она всего лишь осуществляет вывод переданных ей данных.
paul@laika:~$ echo Burtonville
Burtonville
paul@laika:~$ echo Smurfs are blue
Smurfs are blue

Аргументы

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

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

Удаление пробелов

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

Это полностью объясняет эквивалентность следующих четырех команд после их раскрытия средствами командной оболочки.
[paul@RHELv4u3 ~]$ echo Hello World
Hello World
[paul@RHELv4u3 ~]$ echo Hello   World
Hello World
[paul@RHELv4u3 ~]$ echo   Hello   World
Hello World
[paul@RHELv4u3 ~]$    echo      Hello      World
Hello World

Команда echo будет выводить каждый из принятых от командной оболочки аргументов. Также команда echo осуществляет добавление пробелов между всеми принятыми аргументами.

Одинарные кавычки

Вы можете предотвратить удаление пробелов из строки команды, поместив ее в одинарные кавычки. Содержимое экранированной таким образом строки рассматривается как единый аргумент. В примере ниже команда echo принимает только один аргумент.
[paul@RHEL4b ~]$ echo 'Строка с      одинарными    кавычками'
Строка с      одинарными    кавычками
[paul@RHEL4b ~]$

Двойные кавычки

Вы также можете предотвратить удаление пробелов из строки команды, поместив ее в двойные кавычки. Как и в примере выше, команда echo примет только один аргумент.
[paul@RHEL4b ~]$ echo "Строка с      двойными    кавычками"
Строка с      двойными    кавычками
[paul@RHEL4b ~]$

Позднее при обсуждении переменных в рамках данной книги мы разберемся с важными различиями между одинарными и двойными кавычками.

Команда echo и кавычки

Строки, помещенные в кавычки, могут содержать специальные обозначения символов, идентифицируемые командной echo (в случае использования команды echo -e). В примере ниже продемонстрирована методика использования обозначения символа \n для вставки символа переноса строки, а также обозначения символа \t для вставки символа табуляции (обычно эквивалентного восьми символам пробела).
[paul@RHEL4b ~]$ echo -e "Строка с \nсимволом переноса строки"
Строка с 
символом переноса строки
[paul@RHEL4b ~]$ echo -e 'Строка с \nсимволом переноса строки'
Строка с 
символом переноса строки
[paul@RHEL4b ~]$ echo -e "Строка с \tсимволом табуляции"
Строка с     символом табуляции
[paul@RHEL4b ~]$ echo -e ' Строка с \tсимволом табуляции'
Строка с     символом табуляции
[paul@RHEL4b ~]$

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

Команды

Внешние или встроенные команды?

Не все исполняемые командной оболочкой команды являются внешними; некоторые из них являются встроенными. Внешние команды реализованы в форме программ, представленных отдельными бинарными файлами, которые размещены в какой-либо директории файловой системы. Многие бинарные фалы, реализующие функции внешних команд, размещаются в директории /bin или /sbin. Встроенные команды являются неотъемлемой частью самого приложения командной оболочки.

Команда type

Для установления того, будет ли переданная командной оболочке команда исполнена как внешняя команда или как встроенная команда, следует использовать специальную команду type.
paul@laika:~$ type cd
cd is a shell builtin
paul@laika:~$ type cat
cat is /bin/cat

Как вы можете заметить, команда cd является встроенной, а команда cat - внешней.

Также вы можете использовать данную команду для установления того, является ли введенная команда псевдонимом команды.
paul@laika:~$ type ls
ls is aliased to `ls --color=auto'

Исполнение внешних команд

Некоторые команды имеют как встроенные, так и внешние реализации. В случае исполнения одной из таких команд приоритет отдается встроенной реализации. Для исполнения внешней реализации вам придется ввести полный путь к бинарному файлу, являющемуся реализацией данной команды.
paul@laika:~$ type -a echo
echo is a shell builtin
echo is /bin/echo
paul@laika:~$ /bin/echo Исполнение внешней реализации команды echo...
Исполнение внешней реализации команды echo...

Команда which

Команда which осуществляет поиск бинарных файлов в директории, заданной с помощью переменной окружения $PATH (переменные будут рассматриваться позднее). В примере ниже устанавливается, что cd является встроенной командой, а ls, cp, rm, mv, mkdir, pwd и which - внешними командами.
[root@RHEL4b ~]# which cp ls cd mkdir pwd 
/bin/cp
/bin/ls
/usr/bin/which: no cd in (/usr/kerberos/sbin:/usr/kerberos/bin:...
/bin/mkdir
/bin/pwd

Псевдонимы команд

Создание псевдонима команды

Командная оболочка позволяет вам создавать псевдонимы команд (aliases). Псевдонимы команд обычно используются для создания лучше запоминающихся имен для существующих команд или для упрощения передачи параметров команд.
[paul@RHELv4u3 ~]$ cat count.txt 
один
два
три
[paul@RHELv4u3 ~]$ alias dog=tac
[paul@RHELv4u3 ~]$ dog count.txt 
три
два
один

Сокращения команд

Команда создания псевдонима команды (alias) также может оказаться полезной в случае необходимости сокращения длины имени существующей команды.
paul@laika:~$ alias ll='ls -lh --color=auto'
paul@laika:~$ alias c='clear'
paul@laika:~$

Стандартные параметры команд

Псевдонимы команд могут использоваться для передачи командам стандартных параметров. Например, ниже показана методика передачи параметра -i по умолчанию при вводе команды rm.
[paul@RHELv4u3 ~]$ rm -i winter.txt 
rm: удалить обычный файл "winter.txt"? no
[paul@RHELv4u3 ~]$ rm winter.txt 
[paul@RHELv4u3 ~]$ ls winter.txt
ls: невозможно получить доступ к winter.txt: Нет такого файла или каталога
[paul@RHELv4u3 ~]$ touch winter.txt
[paul@RHELv4u3 ~]$ alias rm='rm -i'
[paul@RHELv4u3 ~]$ rm winter.txt 
rm:удалить пустой обычный файл "winter.txt"? no
[paul@RHELv4u3 ~]$

В некоторых дистрибутивах используются стандартные псевдонимы команд для защиты пользователей от случайного удаления файлов ('rm -i', 'mv -i', 'cp -i').

Просмотр объявлений псевдонимов команд

Вы можете передать один или несколько псевдонимов команд в качестве аргументов команды alias для вывода их объявлений. Исполнение команды без аргументов приведет к выводу полного списка используемых на данный момент псевдонимов.
paul@laika:~$ alias c ll
alias c='clear'
alias ll='ls -lh --color=auto'

Команда unalias

Также вы можете прекратить использование псевдонима команды, воспользовавшись командой unalias.
[paul@RHEL4b ~]$ which rm
/bin/rm
[paul@RHEL4b ~]$ alias rm='rm -i'
[paul@RHEL4b ~]$ which rm
alias rm='rm -i'
        /bin/rm
[paul@RHEL4b ~]$ unalias rm
[paul@RHEL4b ~]$ which rm
/bin/rm
[paul@RHEL4b ~]$

Вывод информации о раскрытии команд командной оболочкой

Вы можете активировать режим вывода информации о раскрытии команд командной оболочкой с помощью команды set -x и остановить вывод этой информации с помощью команды set +x. У вас может возникнуть потребность в использовании данной возможности как при изучении данного курса, так и в случаях, когда возникают сомнения насчет того, как командная оболочка обрабатывает переданную вами команду.
[paul@RHELv4u3 ~]$ set -x
++ echo -ne '\033]0;paul@RHELv4u3:~\007'
[paul@RHELv4u3 ~]$ echo $USER
+ echo paul
paul
++ echo -ne '\033]0;paul@RHELv4u3:~\007'
[paul@RHELv4u3 ~]$ echo \$USER
+ echo '$USER'
$USER
++ echo -ne '\033]0;paul@RHELv4u3:~\007'
[paul@RHELv4u3 ~]$ set +x
+ set +x
[paul@RHELv4u3 ~]$ echo $USER
paul

Практическое задание: команды и аргументы

1. Сколько аргументов передается с помощью данной строки команды (не считая самой команды)
touch '/etc/cron/cron.allow' 'file 42.txt' "file 33.txt"

2. Является ли команда tac встроенной?

3. Существует ли действующий псевдоним команды rm?

4. Прочитайте страницу руководства для команды rm и убедитесь в том, что вы поняли предназначение параметра -i этой команды. Создайте и удалите файл для проверки работоспособности параметра -i.

5. Выполните команду: alias rm='rm -i'. Проверьте работоспособность вашего псевдонима команды на тестовом файле. Работает ли он так, как ожидается?

6. Выведите список используемых на данный момент псевдонимов команд.

7a. Создайте псевдоним команды 'city', позволяющий вывести название вашего города.

7b. Используйте ваш псевдоним команды для того, чтобы убедиться в его работоспособности.

8. Выполните команду set -x для активации режима вывода информации о раскрытии каждой из команд командной оболочкой.

9. Проверьте работоспособность команды set -x, воспользовавшись созданными ранее псевдонимами команд city и rm.

10. Выполните команду set +x для прекращения вывода информации о раскрытии команд командной оболочкой.

11. Удалите созданный ранее псевдоним команды city.

12. В каких директориях расположены бинарные файлы, являющиеся реализациями команд cat и passwd?

13. Объясните различие между следующими командами:
echo
/bin/echo
14. Объясните различие между следующими командами:
echo Hello
echo -n Hello

15. Выведите строку "A B C" с двумя пробелами между буквами B и C.

16 (Необязательное задание). Создайте команду (без использования символов пробелов) для формирования следующего вывода:
4+4     =8
10+14   =24
17. Используйте команду echo для формирования следующего вывода:
??\\

Найдите два решения с использованием одинарных кавычек, два решения с использованием двойных кавычек и одно решение без использования кавычек (и поблагодарите Rene и Darioush из компании Google за это дополнение).

18. Используйте одну команду echo для вывода трех слов в трех строках.

Корректная процедура выполнения практического задания: команды и аргументы

1. Сколько аргументов передается с помощью данной строки команды (не считая самой команды)
touch '/etc/cron/cron.allow' 'file 42.txt' "file 33.txt"

Ответ: три аргумента

2. Является ли команда tac встроенной?

type tac

3. Существует ли действующий псевдоним команды rm?

alias rm

4. Прочитайте страницу руководства для команды rm и убедитесь в том, что вы поняли предназначение параметра -i этой команды. Создайте и удалите файл для проверки работоспособности параметра -i.

man rm
touch testfile
rm -i testfile

5. Выполните команду: alias rm='rm -i'. Проверьте работоспособность вашего псевдонима команды на тестовом файле. Работает ли он так, как ожидается?

touch testfile
rm testfile (должен появиться вопрос о подтверждении удаления файла)

6. Выведите список используемых на данный момент псевдонимов команд.

alias

7a. Создайте псевдоним команды 'city', позволяющий вывести название вашего города.

alias city='echo Antwerp'

7b. Используйте ваш псевдоним команды для того, чтобы убедиться в его работоспособности.

city (должна быть выведена строка "Antwerp")

8. Выполните команду set -x для активации режима вывода информации о раскрытии каждой из команд командной оболочкой.

set -x

9. Проверьте работоспособность команды set -x, воспользовавшись созданными ранее псевдонимами команд city и rm.

Командная оболочка должна вывести информацию о разрешении псевдонима, после чего выполнить команду:
paul@deb503:~$ set -x
paul@deb503:~$ city
+ echo antwerp
antwerp

10. Выполните команду set +x для прекращения вывода информации о раскрытии команд командной оболочкой.

set +x

11. Удалите созданный ранее псевдоним команды city.

unalias city

12. В каких директориях расположены бинарные файлы, являющиеся реализациями команд cat и passwd?

which cat (вероятно /bin/cat)
which passwd (вероятно /usr/bin/passwd)
13. Объясните различие между следующими командами:
echo
/bin/echo

После интерпретации команды echo командной оболочкой будет задействована встроенная реализация команды echo. Ввод команды /bin/echo приведет к исполнению бинарного файла echo, расположенного в директории /bin.

14. Объясните различие между следующими командами:
echo Hello
echo -n Hello

Параметр -n команды echo предназначен для предотвращения вывода символа перехода на новую строку в конце переданной строки. Команда echo Hello выведет в общей сложности шесть символов, а команда echo -n Hello - только пять символов.

(Параметр -n может не работать в командной оболочке Korn shell).

15. Выведите строку "A B C" с двумя пробелами между буквами B и C.

echo "A B  C"
16 (Необязательное задание). Создайте команду (без использования символов пробелов) для формирования следующего вывода:
4+4     =8
10+14   =24
Решение заключается в использовании символов табуляции с помощью специального обозначения \t.
echo -e "4+4\t=8" ; echo -e "10+14\t=24"
17. Используйте команду echo для формирования следующего вывода:
??\\

Найдите два решения с использованием одинарных кавычек, два решения с использованием двойных кавычек и одно решение без использования кавычек (и поблагодарите Rene и Darioush из компании Google за это дополнение).

echo '??\\'
echo -e '??\\\\'
echo "??\\\\"
echo -e "??\\\\\\"
echo ??\\\\

18. Используйте одну команду echo для вывода трех слов в трех строках.

echo -e "один \nдва \nтри"


Предыдущий раздел: Оглавление Следующий раздел:
Глава 9. Дерево директорий Linux   Глава 11. Операторы управления