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

UnixForum





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

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

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

Глава 15. Формирование списков имен файлов на основе шаблонов

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

Звездочка (*)

Звездочка * интерпретируется командной оболочкой как символ для генерации списка имен файлов, причем сам символ звездочки может преобразовываться в любую комбинацию символов (или даже в строку без символов). В том случае, если не задано пути к директории для формирования списка имен файлов, командная оболочка будет использовать имена файлов из текущей директории. Обратитесь к странице руководства glob(7) для получения дополнительной информации. (Данный вопрос также рассматривается в теме LPI 1.103.3.)
[paul@RHELv4u3 gen]$ ls
file1  file2  file3  File4  File55  FileA  fileab  Fileab  FileAB  fileabc
[paul@RHELv4u3 gen]$ ls File*
File4  File55  FileA  Fileab  FileAB
[paul@RHELv4u3 gen]$ ls file*
file1  file2  file3  fileab  fileabc
[paul@RHELv4u3 gen]$ ls *ile55
File55
[paul@RHELv4u3 gen]$ ls F*ile55
File55
[paul@RHELv4u3 gen]$ ls F*55
File55
[paul@RHELv4u3 gen]$

Знак вопроса (?)

Аналогично звездочке, знак вопроса ? интерпретируется командной оболочкой как символ для генерации списка имен файлов, причем сам знак вопроса соответствует ровно одному символу имени файла.
[paul@RHELv4u3 gen]$ ls
file1  file2  file3  File4  File55  FileA  fileab  Fileab  FileAB  fileabc
[paul@RHELv4u3 gen]$ ls File?
File4  FileA
[paul@RHELv4u3 gen]$ ls Fil?4
File4
[paul@RHELv4u3 gen]$ ls Fil??
File4  FileA
[paul@RHELv4u3 gen]$ ls File??
File55  Fileab  FileAB
[paul@RHELv4u3 gen]$

Квадратные скобки ([])

Открывающаяся квадратная скобка [ интерпретируется командной оболочкой как символ для генерации списка имен файлов, соответствующий любым из символов, находящихся между символом [ и первым следующим за ним символом ]. Порядок следования символов в списке между скобками не имеет значения. Каждая пара символов скобок заменяется ровно на один символ.
[paul@RHELv4u3 gen]$ ls 
file1  file2  file3  File4  File55  FileA  fileab  Fileab  FileAB  fileabc
[paul@RHELv4u3 gen]$ ls File[5A]
FileA
[paul@RHELv4u3 gen]$ ls File[A5]
FileA
[paul@RHELv4u3 gen]$ ls File[A5][5b]
File55
[paul@RHELv4u3 gen]$ ls File[a5][5b]
File55  Fileab
[paul@RHELv4u3 gen]$ ls File[a5][5b][abcdefghijklm]
ls: невозможно получить доступ к File[a5][5b][abcdefghijklm]: Нет такого файла или каталога
[paul@RHELv4u3 gen]$ ls file[a5][5b][abcdefghijklm]
fileabc
[paul@RHELv4u3 gen]$
Также с помощью символа восклицательного знака ! вы можете исключать символы из списка, расположенного между квадратными скобками. Кроме того, у вас имеется возможность создания комбинаций из описанных выше шаблонов.
[paul@RHELv4u3 gen]$ ls 
file1  file2  file3  File4  File55  FileA  fileab  Fileab  FileAB  fileabc
[paul@RHELv4u3 gen]$ ls file[a5][!Z]
fileab
[paul@RHELv4u3 gen]$ ls file[!5]*
file1  file2  file3  fileab  fileabc
[paul@RHELv4u3 gen]$ ls file[!5]?
fileab
[paul@RHELv4u3 gen]$

Диапазоны a-z и 0-9

Командная оболочка bash также распознает объявления диапазонов символов между квадратными скобками.
[paul@RHELv4u3 gen]$ ls
file1  file3  File55  fileab  FileAB   fileabc
file2  File4  FileA   Fileab  fileab2
[paul@RHELv4u3 gen]$ ls file[a-z]*
fileab  fileab2  fileabc
[paul@RHELv4u3 gen]$ ls file[0-9]
file1  file2  file3
[paul@RHELv4u3 gen]$ ls file[a-z][a-z][0-9]*
fileab2
[paul@RHELv4u3 gen]$

Переменная окружения $LANG и квадратные скобки

В ходе работы с командной оболочкой не стоит забывать о влиянии на процесс генерации имен файлов значения переменной окружения LANG. Причина этого влияния заключается в том, что в некоторых языках строчные буквы включаются в диапазон прописных букв (и наоборот).
paul@RHELv4u4:~/test$ ls [A-Z]ile?
file1  file2  file3  File4
paul@RHELv4u4:~/test$ ls [a-z]ile?
file1  file2  file3  File4
paul@RHELv4u4:~/test$ echo $LANG
en_US.UTF-8
paul@RHELv4u4:~/test$ LANG=C
paul@RHELv4u4:~/test$ echo $LANG
C
paul@RHELv4u4:~/test$ ls [a-z]ile?
file1  file2  file3
paul@RHELv4u4:~/test$ ls [A-Z]ile?
File4
paul@RHELv4u4:~/test$

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

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

В примере ниже не должно быть ничего удивительного. При использовании команды echo * в пустой директории будет выведен символ *. А при использовании той же команды в директории с файлами будут выведены имена всех файлов.
paul@ubu1010:~$ mkdir test42
paul@ubu1010:~$ cd test42
paul@ubu1010:~/test42$ echo *
*
paul@ubu1010:~/test42$ touch file42 file33
paul@ubu1010:~/test42$ echo *
file33 file42
Формирование списков имен файлов на основе шаблонов может быть предотвращено путем помещения специальных символов в кавычки, а также экранирования этих символов таким образом, как показано в примере ниже.
paul@ubu1010:~/test42$ echo *
file33 file42
paul@ubu1010:~/test42$ echo \*
*
paul@ubu1010:~/test42$ echo '*'
*
paul@ubu1010:~/test42$ echo "*"
*

Практическое задание: формирование списков имен файлов на основе шаблонов

1. Создайте тестовую директорию и перейдите в нее.

2. Создайте следующие файлы:
file1
file10
file11
file2
File2
File3
file33
fileAB
filea
fileA
fileAAA
file(
file 2

(Имя последнего файла состоит из 6 символов, включая пробел).

3. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с строки file.

4. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с строки File.

5. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с строки file и заканчиваются числовым символом.

6. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с строки file и заканчиваются буквенным символом.

7. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с строки File и имеют пятый числовой символ.

8. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с строки File, имеют пятый числовой символ и никаких символов более.

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

10. Выведите список всех имен файлов (с помощью команды ls), которые состоят ровно из пяти символов.

11. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с символа f или F и оканчиваются символом 3 или A.

12. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с символа f и оканчиваются числовым символом, причем вторым символом является символ i или R.

13. Выведите список всех имен файлов (с помощью команды ls), которые не начинаются с символа F.

14. Скопируйте значение переменной окружения $LANG в значение переменной окружения $MyLANG.

15. Продемонстрируйте влияние значения переменной окружения $LANG на вывод имен файлов с буквенными символами из диапазонов A-Z или a-z.

16. Вы получили информацию о том, что один из ваших серверов был взломан, причем взломщик, вероятнее всего, подменил бинарный файл с реализацией команды ls. Вы знаете о том, что использование команды echo не несет опасности. Можно ли заменить команду ls командой echo? Как вы будете выводить список файлов в текущей директории с помощью команды echo?

17. Существуют ли другие команды, помимо cd, предназначенные для изменения текущей директории?

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

1. Создайте тестовую директорию и перейдите в нее.

mkdir testdir; cd testdir
2. Создайте следующие файлы:
file1
file10
file11
file2
File2
File3
file33
fileAB
filea
fileA
fileAAA
file(
file 2

(Имя последнего файла состоит из 6 символов, включая пробел).

touch file1 file10 file11 file2 File2 File3
touch file33 fileAB filea fileA fileAAA
touch "file("
touch "file 2"

3. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с строки file.

ls file*

4. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с строки File.

ls File*

5. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с строки file и заканчиваются числовым символом.

ls file*[0-9]

6. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с строки file и заканчиваются буквенным символом.

ls file*[a-z]

7. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с строки File и имеют пятый числовой символ.

ls File[0-9]*

8. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с строки File, имеют пятый числовой символ и никаких символов более.

ls File[0-9]

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

ls [a-z]*[0-9]

10. Выведите список всех имен файлов (с помощью команды ls), которые состоят ровно из пяти символов.

ls ?????

11. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с символа f или F и оканчиваются символом 3 или A.

ls [fF]*[3A]

12. Выведите список всех имен файлов (с помощью команды ls), которые начинаются с символа f и оканчиваются числовым символом, причем вторым символом является символ i или R.

ls f[iR]*[0-9]

13. Выведите список всех имен файлов (с помощью команды ls), которые не начинаются с символа F.

ls [!F]*

14. Скопируйте значение переменной окружения $LANG в значение переменной окружения $MyLANG.

MyLANG=$LANG

15. Продемонстрируйте влияние значения переменной окружения $LANG на вывод имен файлов с буквенными символами из диапазонов A-Z или a-z.

Обратитесь к примеру в книге.

16. Вы получили информацию о том, что один из ваших серверов был взломан, причем взломщик, вероятнее всего, подменил бинарный файл с реализацией команды ls. Вы знаете о том, что использование команды echo не несет опасности. Можно ли заменить команду ls командой echo? Как вы будете выводить список файлов в текущей директории с помощью команды echo?

echo *

17. Существуют ли другие команды, помимо cd, предназначенные для изменения текущей директории?

pushd popd


Предыдущий раздел: Оглавление Следующий раздел:
Глава 14. История команд командной оболочки   16. Перенаправление потоков ввода/вывода