Различия между версиями 11 и 12
Версия 11 от 2008-07-24 21:08:11
Размер: 13252
Редактор: MaximByshevskiKonopko
Комментарий:
Версия 12 от 2008-07-30 00:42:54
Размер: 12145
Редактор: Allena
Комментарий:
Удаления помечены так. Добавления помечены так.
Строка 3: Строка 3:
=== Перенаправление ввода-вывода. === == Перенаправление ввода вывода ==
Строка 5: Строка 5:
Мы уже говорили, что программа когда запускается, то ей сразу передаётся три файловых дескрипотра --- стандартный ввод (0), стандартный вывод (1) и стандартный поток ошибок (2). Открытием этих файлов занимается ОС, прграмма запущенная уже получает их открытыми. Её дело --- читать из 0, выводить 1 и ошибаться в 2. Не её дело открывать их и закрывать. Это очень удобно, потому что по умолчанию все три потока ассоциируются с терминалом. Нпример, прграмма cat довольно бессмысленна сама по себе --- читает из stdin и выводит в stdout. Как уже упоминалось, любая программа имеет доступ к трем инициализированным перед ее запуском файловым дескрипторам: 0 (стандартный поток ввода, stdin), 1 (стандартный поток вывода, stdout) и 2(стандартный поток ошибок, stderr). Подготовкой этих файлов занимаются ОС и иногда запускающий процесс, программа получает уже готовые к использованию дескрипторы. По умолчанию все три дескриптора ассоциируются с терминалом.
В качестве наглядной демонстрации удобства подобного подхода рассмотрим утилиту cat. Сама по себе она достаточно бессмысленна --- читает данные из stdin и выводит их в stdout.
Строка 11: Строка 12:
Но если программа, которая её запускает, подсунет ей другие дескрипторы, то оно так и будет, средствами шелла это делается при помощи <, > и >>. В первом случае перенаправление на стандартного потока ввода, во втором и третьем --- стандартного потока вывода в файл.
Но существует возможность при запуске программы изменить файлы, ассоциированные с стандартными потоками. Например, шелл позволяет сделать это при помощи операторов <, > и >>. "<" перенаправляет стандартный потока ввода, ">" --- стандартный потока вывода, затирая старое содержимое аргумента, ">>" перенаправляет стандартный поток вывода, добаввляя его содержимое в конец файла-аргумента.
Строка 29: Строка 31:
}}} }}} 
Строка 31: Строка 33:
Для перенаправления stderr надо использовать 2> filename. (у утилиты cat нету ключа --l, и она выдаёт диагностику в стандартный поток ошибок).
Перенаправление стандартного потока ошибок в шелле реализуется конструкцией "2> filename".
Например, у утилиты cat нет ключа --l, и если попытатся вызвать ее с ним, она выведет диагностическое сообщение в стандартный поток ошибок.
Строка 34: Строка 36:
$ cat --l < File > .FileFileFile 2>Error $ cat --l < File > .FileFile 2>Error
Строка 39: Строка 41:
При этом при первом вызове `cat` ничего на экран не попало, всё ушло в файлы. Еще более интересным и многообещающим является возможность ассоциирования стандартного потока вывода одной программы с стандартным потоком ввода другой. В шелле это организуется оператором |. Обычно для реализации этой функциональности на системном уровне используются безымянные pipe.
Строка 41: Строка 43:
Ещё более интересным и мнгообещающим является перенаправление stdout однй программы на stdin другой. При этом происходит такая штука: создаётся безымянный pipe, который в ФС отсутствует, но позволяет передавать данные между процессами.

Команда cal выводит календарь на месяц, раскрашивая сегодняшний день, поскольку она определяет, что stdout --- терминал. `cal | cat` организует перенаправление при помощи безымянного канала, при этом `cal` определяет, что stdout не терминал и ничего не раскрашивает.
Программа cal выводит календарь на месяц. Если с потоком вывода проассоциирован терминал, то cal раскрашивает текущий день. В противном случае выводится просто текст. Например, при вызове `cal | cat` выделения цветом не будет (так как потоком вывода для cal будет безымянный канал).
Строка 53: Строка 53:
}}}     }}}
Строка 55: Строка 55:
Программа `wc` выводит количество символов-слов-переводов строк. Утилита `wc` выводит количество символов/слов/переводов строк в стандартном потоке ввода.
Строка 61: Строка 61:
Можно делать длинные конфейеры: `cal | tac | tac` (утилита tac выводит поступившие ей строки в обратном порядке, тем самым, если применить её два раза, ничего не произойдёт): Можно делать длинные конвейеры: `cal | tac | tac` (утилита tac выводит поступившие ей строки в обратном порядке, так что, если применить её два раза, ничего не произойдёт):
Строка 78: Строка 78:
Эта штука, перенаправление, очень эффективна, и почти любой сценарий этим пользуется. Перенаправление --- очень эффективный интрумент, использующийся практически в любом шелл-сценарии.
Строка 80: Строка 80:
Всякие способы работы с шеллом. == Для чего нужен шелл? ==
Шелл выполняет 3 функции:
Строка 82: Строка 83:
Шелл --- штука триединая. Тот интерпретатор, с которым мы работаем, выполняет три функции:
 * Удобство работы с командной строкой. Например, истроия и tab completion. То есть, интерфейс взаимодействия с пользователем.
 * Это оболочка или интегратор. Основное в программном окружении --- утилиты, которые обеспечивают командный интерфейс к ядру. Утилиты сами по семе решают одну очень небольшую задачу по добыче или преобразованию текстововой информации (например, ls добывает, sort преобразует). При этом тот факт, что эти утилиты можно как-то друг к другу приклепать и сделать так, чтбы они работали совместно, то есть построить решение пользовательской задачи --- обеспечивается именно шеллом. Подобное удобство манипулирования и интегрирования утилит представляет только шелл, поскольку это является его основной задачей.
 * Непосредственное построение решения, язык программирования. Это полноценный высокоуровневый язык, объектами которого являются объекты файловой системы.
 * Предоставляет удобные средства для работы с командной строкой. Например, историю команд и дополнение по tab.
Строка 87: Строка 85:
Что касается второй: мы немного поработали с фалами, у нас есть механизм передачи информации от одного процесса другому. Если мы говорим, что шелл --- ЯП, то надо бы иметь переменные. Мы можем присвоить переменной значение. Обратите внимание на две вещи: переменные все строковые. Почему --- потому что вычислительные задачи лучше решать на языке, пригодном для вычислений, и использовать подобные написанные программы, интегрируя их с другими шеллом. Имя переменной инициализируется в первом присваивании, значение переменной --- $имя.  * Предоставляет возможность комбинировать и интегрировать различные утилиты. Каждая утилита, сама по себе, обычно решает небольшую задачу, при этом получая данные и выдавая результат в текстовом виде. В такой схеме перенаправление ввода-вывода позволяет реализовать совместную работу нескольких утилит, и, таким образом, решить пользовательскую задачу. Подобное удобство манипулирования утилитами предоставляет только шелл, и именно это является его основной функцией.

 * И, наконец, шелл --- это полноценный высокоуровневый язык программирования, оперирующий объектами файловой системы.

== Переменные ==
Как в любом языке программирования, в шелле есть перменные. В силу особенностей назначения шелла все переменные в нем являются строковыми.

Пример инициализации переменной:
Строка 93: Строка 98:
Это в общем показало нам шелл как некий извращённый язык программирования, если бы не одна особенность.
Строка 95: Строка 99:
Текущий каталог входит в окружение процесса, то есть любой процесс в системе имеет в своём контексте тот каталог, который является текущим. На самом деле, в этот контекст входит не только текущий каталог. В окружение входят дескрипторы всех открытых файлов, идентификатор пользователя, идентификатор группы, и куча других переменных. Но у них какое-то значимое содержимое, каждая что-то значит. Более того, при форке процесса наследуется окружение. Важно, что переменная HOME была определена при логине и все процессы пользователя получают её в наследие от шелла, который запускается при логине (login shell). Кроме этго, есть много других переменных --- пользователь, имя шелла... Очень важная переменная PATH содержит список каталогов, в которых шелл ищет исполнимые файлы, если данное имя команды не является встроенным.
{{{
Переменные автоматически передаются процессам, запущенным из шелла, в качестве части окружения процесса. Окружение процесса --- это набор достаточно разнообразнй информации, связанный с процессом. Туда входят, например, текущий каталог, дескрипторы открытых файлов, и т. п. При fork окружение практически полностью наследуется. Некоторые переменные, например HOME или PATH определяются при входе пользователя в систему, в так называемом login shell, и от него наследуются всеми процессами, запущенными пользователем.
Переменная PATH содержит список каталагов, в которых шелл ищет исполняемые файлы.
 {{{
Строка 100: Строка 105:
В отличие от DOS, текущий каталог не используется при поиске программы. Заметим, что в отличие от DOS, текущий каталог в PATH не включен.

Основы использования командной строки

Перенаправление ввода вывода

Как уже упоминалось, любая программа имеет доступ к трем инициализированным перед ее запуском файловым дескрипторам: 0 (стандартный поток ввода, stdin), 1 (стандартный поток вывода, stdout) и 2(стандартный поток ошибок, stderr). Подготовкой этих файлов занимаются ОС и иногда запускающий процесс, программа получает уже готовые к использованию дескрипторы. По умолчанию все три дескриптора ассоциируются с терминалом. В качестве наглядной демонстрации удобства подобного подхода рассмотрим утилиту cat. Сама по себе она достаточно бессмысленна --- читает данные из stdin и выводит их в stdout.

$ cat  
Hello                       
Hello                 

Но существует возможность при запуске программы изменить файлы, ассоциированные с стандартными потоками. Например, шелл позволяет сделать это при помощи операторов <, > и >>. "<" перенаправляет стандартный потока ввода, ">" --- стандартный потока вывода, затирая старое содержимое аргумента, ">>" перенаправляет стандартный поток вывода, добаввляя его содержимое в конец файла-аргумента.

$ cat >> File
Hello                       
$ cat < File
Hello                       
$ cat >> File
I love you                  
$ cat < File
Hello                       
I love you                  
$ cat > File
Hello?                      
$ cat < File
Hello?                      
$ cat < File > .FileFile
$ cat .FileFile
Hello?                      

Перенаправление стандартного потока ошибок в шелле реализуется конструкцией "2> filename". Например, у утилиты cat нет ключа --l, и если попытатся вызвать ее с ним, она выведет диагностическое сообщение в стандартный поток ошибок.

$ cat --l < File > .FileFile 2>Error
$ cat Error
cat: нераспознанный ключ `--l'

Еще более интересным и многообещающим является возможность ассоциирования стандартного потока вывода одной программы с стандартным потоком ввода другой. В шелле это организуется оператором |. Обычно для реализации этой функциональности на системном уровне используются безымянные pipe.

Программа cal выводит календарь на месяц. Если с потоком вывода проассоциирован терминал, то cal раскрашивает текущий день. В противном случае выводится просто текст. Например, при вызове cal | cat выделения цветом не будет (так как потоком вывода для cal будет безымянный канал).

$ cal | cat
     Июль 2008              
Вс Пн Вт Ср Чт Пт Сб        
       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 31     

Утилита wc выводит количество символов/слов/переводов строк в стандартном потоке ввода.

$ cal | wc
      8      40     186 

Можно делать длинные конвейеры: cal | tac | tac (утилита tac выводит поступившие ей строки в обратном порядке, так что, если применить её два раза, ничего не произойдёт):

$ cal | tac | tac
     Июль 2008              
Вс Пн Вт Ср Чт Пт Сб        
       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 31           

cal | head -2 | tail -1 (утилита head выводит заданное количество первых строк ввода, tail --- последних. Комбинируя эти утилиты, можно получить произвольный срез файла по строкам):

$ cal | head -2 | tail -1
Вс Пн Вт Ср Чт Пт Сб 

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

Для чего нужен шелл?

Шелл выполняет 3 функции:

  • Предоставляет удобные средства для работы с командной строкой. Например, историю команд и дополнение по tab.
  • Предоставляет возможность комбинировать и интегрировать различные утилиты. Каждая утилита, сама по себе, обычно решает небольшую задачу, при этом получая данные и выдавая результат в текстовом виде. В такой схеме перенаправление ввода-вывода позволяет реализовать совместную работу нескольких утилит, и, таким образом, решить пользовательскую задачу. Подобное удобство манипулирования утилитами предоставляет только шелл, и именно это является его основной функцией.
  • И, наконец, шелл --- это полноценный высокоуровневый язык программирования, оперирующий объектами файловой системы.

Переменные

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

Пример инициализации переменной:

$ VAR="Value Value"
$ echo $VAR
Value Value

Переменные автоматически передаются процессам, запущенным из шелла, в качестве части окружения процесса. Окружение процесса --- это набор достаточно разнообразнй информации, связанный с процессом. Туда входят, например, текущий каталог, дескрипторы открытых файлов, и т. п. При fork окружение практически полностью наследуется. Некоторые переменные, например HOME или PATH определяются при входе пользователя в систему, в так называемом login shell, и от него наследуются всеми процессами, запущенными пользователем. Переменная PATH содержит список каталагов, в которых шелл ищет исполняемые файлы.

  • $ echo $PATH
    /home/george/bin:/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:/usr/games

Заметим, что в отличие от DOS, текущий каталог в PATH не включен.

Подстановки.

Чтобы дать пример того, насколько мощным интегратором является шелл, рассмотрим ещё одну вещь. Обратите внимание на то, каким образом переменной присваивается значение с пробелом. Закавычивание для параметра с пробелами сохраняет его в том виде, в котором он написан внутри кавычек. Если без кавычек, то будет иначе.

$ echo "$VAR"
Value                   Value
$ echo $VAR
Value Value

Генерация список файлов по шаблону (FNG, FileName Generation). Что это такое? Когда вы хотите совершить групповую операцию над файлами, то для задания групп используются специальные символы: * --- любое количество символов, ? --- один символ, [abc] или [a-z] --- символ из диапазона, [^a-z] --- символ не из диапазона.

Например, echo F*.

$ echo F*
FFFFF FFFile1 FFFile2 File File1 File2 File3 File4 File45

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

$ echo File??
File45                      
$ echo File[2-4]
File2 File3 File4           
$ echo File[^2-4]
File1                       
$ echo File[2-4F*]
File2 File3 File4           
$ echo File[2-4F]*
File2 File3 File4 File45    

Кто превратил F* в список файлов? Шелл. Когда шелл видит спецсимвол, то он применяет шаблон к именам файлов. Какие вещи не стоит забывать при использовании FNG: этим занимается шелл, и прграмма ничего об этом не знает. Второе --- файлы с точки не включаются в FNG по умолчанию. При этом .* включит файлы . и .., что не всегда хорошо. {{{$ echo .* . .. .FileFile .FileFileFile }}} Общего решения для этого нет, но в частных случаях можно попробовать исключения (.[^.]* ..?*):

$ echo .[^.]*
.FileFile .FileFileFile


Сведения о ресурсах

Готовность (%)

Продолжительность (ак. ч.)

Подготовка (календ. ч.)

Полный текст (раб. д.)

Предварительные знания

Level

Maintainer

Start date

End date

20

1

1

1

1

MaximByshevskiKonopko, Allena, VsevolodKrishchenko


CategoryLectures CategoryPspo CategoryMpgu CategoryUneex

PspoClasses/080717/04ConsoleBasics (последним исправлял пользователь eSyr 2012-05-27 15:01:26)