Что такое shell команды. Специальные символы в shell. Что делать, когда что-то непонятно

Что такое shell команды. Специальные символы в shell. Что делать, когда что-то непонятно

22.04.2019

Командный язык shell (в переводе - раковина, скорлупа) фактически есть язык программирования очень высокого уровня. На этом языке пользователь осуществляет управление компьютером. Обычно, после входа в систему вы начинаете взаимодействовать с командной оболочкой. Признаком того, что оболочка (shell) готова к приему команд служит выдаваемый ею на экран промптер. В простейшем случае это один доллар ("$"). Shell не является необходимым и единственным командным языком (хотя именно он стандартизован в рамках POSIX - стандарта мобильных систем). Например, немалой популярностью пользуется язык cshell, есть также kshell, bashell и другие. Более того, каждый пользователь может создать свой командный язык. Может одновременно на одном экземпляре операционной системы работать с разными командными языками. shell - это одна из многих команд UNIX. То есть в набор команд оболочки "shell" входит команда "sh" - вызов интерпретатора "shell". Первый "shell" вызывается автоматически при вашем входе в систему и выдает на экран промтер. После этого вы можете вызывать на выполнение любые команды, в том числе и снова сам "shell", который вам создаст новую оболочку внутри прежней. Так например, если вы подготовите в редакторе файл "file_1":

Echo Hello!

то это будет обычный текстовый файл, содержащий команду "echo", которая при выполнении выдает все написанное правее ее на экран. Можно сделать файл "file_1" выполняемым с помощью команды "chmod 755 file_1". Но его можно выполнить, вызвав явно команду "sh" ("shell"):

Sh file_1

Sh < file1

Файл можно выполнить и в текущем экземпляре "shell". Для этого существует специфическая команда "." (точка), т.е.

File_1

Поскольку UNIX - система многопользовательская, вы можете даже на персональном компьютере работать параллельно, скажем, на 12-ти экранах (переход с экрана на экран ALT/функциональная клавиша), имея на каждом экране нового (или одного и того же) пользователя со своей командной оболочкой. Можете и в графическом режиме X-Window также открыть большое число окон, а в каждом окне может быть свой пользователь со своей командной оболочкой... Стержневым элементом языка shell является команда.

Структуры команд:

Команды в shell обычно имеют следующий формат:

<имя команды> <флаги> <аргумент(ы)>

Например:

Ls -ls /usr/bin

Где ls - имя команды выдачи содержимого директория, -ls - флаги ("-" - признак флагов, l - длинный формат, s - об"ем файлов в блоках), /usr/bin - директорий, для которого выполняется команда. Эта команда выдаст на экран в длинном формате содержимое директория /usr/bin, при этом добавит информацию о размере каждого файла в блоках. К сожалению, такая структура команды выдерживается далеко не всегда. Не всегда перед флагами ставится минус, не всегда флаги идут одним словом. Есть разнообразие и в представлении аргументов. К числу команд, имеющих экзотические форматы, относятся и такие "ходовые" команды, как сс - вызов компилятора языка С, tar - работа с архивами, dd - копирование файла с преобразованием, find - поиск файлов и ряд других. Как правило, первое слово shell воспринимает, как команду. Поэтому в командной строке

первое слово будет расшифровано shell, как команда (конкатенации), которая выдаст на экран файл с именем "cat" (второе слово), находящийся в текущем директории. Перенаправление команд Стандартный ввод (вход) - "stdin" в ОС UNIX осуществляется с клавиатуры терминала, а стандартный вывод (выход) - "stdout" направлен на экран терминала. Существует еще и стандартный файл диагностических сообщений - "stderr", о котором речь будет чуть позже. Команда, которая может работать со стандартным входом и выходом, называется ФИЛЬТРОМ. Пользователь имеет удобные средства перенаправления ввода и вывода на другие файлы (устройства). Символы ">" и ">>" обозначают перенаправление вывода. ls >file_1 команда "ls" сформирует список файлов текущего каталога и поместит его в файл "file_1" (вместо выдачи на экран). Если файл "file_1" до этого существовал, то он будет затерт новым.

Pwd >>file_1

команда pwd сформирует полное имя текущего каталога и поместит его в конец файла "file_1", т.е. ">>" добавляет в файл, если он непустой. Символы "<" и "<<" обозначают перенаправление ввода.

Wc -l

подсчитает и выдаст на экран число строк в файле file_1.

Ed file_2 <

создаст с использованием редактора файл "file_2", непосредственно с терминала. Окончание ввода определяется по символу, стоящему правее "<<" (т. е. "!"). То есть ввод будет закончен, когда первым в очередной строке будет "!". Можно сочетать перенаправления. Так

Wc -l file_4

Wc -l >file_4

выполняются одинаково: подсчитывается число строк файла "file_3" и результат помещается в файл "file_4". Средство, объединяющее стандартный выход одной команды со стандартным входом другой, называется КОНВЕЙЕРОМ и обозначается вертикальной чертой "|".

Ls | wc -l

список файлов текущего каталога будет направлен на вход команды "wc", которая на экран выведет число строк каталога. Конвейером можно объединять и более двух команд, когда все они, возможно кроме первой и последней - фильтры:

Cat file_1 | grep -h result | sort | cat -b > file_2

Данный конвейер из файла "file_1" ("cat") выберет все строки, содержащие слово "result" ("grep"), отсортирует ("sort") полученные строки, а затем пронумерует ("cat -b") и выведет результат в файл "file_2". Поскольку устройства в ОС UNIX представлены специальными файлами, их можно использовать при перенаправлениях. Специальные файлы находятся в каталоге "/dev". Например, "lp" - печать; "console" - консоль; "ttyi" - i-ый терминал; "null" - фиктивный (пустой) файл (устройство). Тогда, например,

Ls > /dev/lp

выведет содержимое текущего каталога на печать, а file_1 < /dev/null обнулит файл "file_1".

Sort file_1 | tee /dev/lp | tail -20

В этом случае будет отсортирован файл "file_1" и передан на печать, а 20 последних строк также будут выданы на экран. Вернемся к перенаправлению выхода. Стандартные файлы имеют номера:

0 - stdin, 1 - stdout 2 - stderr. Если вам не желательно иметь на экране сообщение об ошибке, вы можете перенаправить его с экрана в указанный вами файл (или вообще "выбросить", перенаправив в файл "пустого устройства" - /dev/null). Например при выполнении команды

Cat file_1 file_2

которая должна выдать на экран последовательно содержимое файлов "file_1" и "file_2", выдаст вам, например, следующее

111111 222222 cat: f2: No such file or directory

где 111111 222222 - содержимое файла "file_1", а файл "file_2" отсутствует, о чем команда "cat" выдала сообщение в стандартный файл диагностики, по умолчанию, как и стандартный выход, представленный экраном. Если вам не желательно такое сообщение на экране, его можно перенаправить в указанный вами файл:

Cat file_1 file_2 2>f-err

сообщения об ошибках будут направляться (об этом говорит перенаправление "2>") в файл "f-err". Кстати, вы можете всю информацию направлять в один файл "ff", использовав в данном случае конструкцию

Cat file_1 file_2 >>ff 2>ff

Можно указать не только какой из стандартных файлов перенаправлять, но и в какой стандартный файл осуществить перенаправление.

Cat file_1 file_2 2>>ff 1>&2

Здесь сначала "stderr" перенаправляется (в режиме добавления) в файл "ff", а затем стандартный выход перенаправляется на "stderr", которым к этому моменту является файл "ff". То есть результат будет аналогичен предыдущему. Конструкция "1>&2" - означает, что кроме номера стандартного файла, в который перенаправить, необходимо впереди ставить "&"; вся конструкция пишется без пробелов. <- закрывает стандартный ввод. >- закрывает стандартный вывод. Командные файлы. Для того, чтобы текстовый файл можно было использовать как команду, существует несколько возможностей. Пусть с помощью редактора создан файл с именем "cmd", содержащий одну строку следующего вида:

Date; pwd; ls

Можно вызвать shell как команду, обозначаемую "sh", и передать ей файл "cmd", как аргумент или как перенаправленный вход, т.е.

$ sh cmd

$ sh

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

Chmod 711 cmd

сделает код защиты "rwx__x__x". Тогда простой вызов

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

Date; pwd; ls

представлен в виде: date pwd ls так как переход на другую строку также является разделителем в последовательности команд. Таким образом, выполняемыми файлами могут быть не только файлы, полученные в результате компиляции и сборки, но и файлы, написанные на языке shell. Их выполнение происходит в режиме интерпретации с помощью shell-интерпретатора

Отладка командных файлов

В SHELL используются два механизма отладки командных файлов. Первый из них: set -v выводит строки командного файла по мере их чтения. Этот режим применяется при поиске синтаксических ошибок. Для его использования не требуется производить модификацию командного файла, например: sh -v proc... здесь proc - имя командного файла. Ключ -v может использоваться вместе с ключом -n, предотвращающим выполнение следующих за ним команд (команда set -n блокирует терминал до тех пор, пока не вводится признак конца файла EOF). Команда set -х выводит команды по мере их выполнения, причём на терминал выводятся строки программы и на место переменных подставляются их значения. Для отмены ключей -x и -v можно воспользоваться командой set - а для установки - присвоить соответствующее значение макропеременной. СРЕДА SHELL (ПЕРЕМЕННЫЕ И ПАРАМЕТРЫ) На языке shell можно писать командные файлы и с помощью команды "chmod" делать их выполняемыми. После этого они ни чем не отличаются от прочих команд ОС UNIX.

Shell-переменные

Имя shell-переменной - это начинающаяся с буквы последовательность букв, цифр и подчеркиваний. Значение shell-переменной - строка символов. То, что в shell всего два типа данных: строка символов и текстовый файл, с одной стороны, позволяет легко вовлекать в программирование конечных пользователей, никогда ранее программированием не занимавшихся, а с другой стороны, вызывает некий внутренний протест у многих программистов, привыкших к существенно большему разнообразию и большей гибкости языковых средств. Однако интересно наблюдать то, как высококлассные программисты, освоившись с "правилами игры" shell, пишут на нем программы во много раз быстрее, чем на Си, но, что особенно интересно, в ряде случаев эти программы работают даже быстрее, чем реализованные на Си. Имя переменной аналогично традиционному представлению об идентификаторе, т.е. именем может быть последовательность букв, цифр и подчеркиваний, начинающаяся с буквы или подчеркивания. Для присваивания значений переменным может использоваться оператор присваивания "=".

Var_1=13 - "13" - это не число, а строка из двух цифр. var_2="ОС UNIX" - здесь двойные кавычки (" ") необходимы, так как в строке есть пробел.

Возможны и иные способы присваивания значений shell-переменным. Так например запись,

DAT=`date`

приводит к тому, что сначала выполняется команда "date" (обратные кавычки говорят о том, что сначала должна быть выполнена заключенная в них команда), а результат ее выполнения, вместо выдачи на стандартный выход, приписывается в качестве значения переменной, в данном случае "DAT". Можно присвоить значение переменной и с помощью команды "read", которая обеспечивает прием значения переменной с (клавиатуры) дисплея в диалоговом режиме. Обычно команде "read" в командном файле предшествует команда "echo", которая позволяет предварительно выдать какое-то сообщение на экран. Например:

Echo -n "Введите трехзначное число:" read x

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

Введите трехзначное число:

интерпретатор остановится и будет ждать ввода значения с клавиатуры. Если вы ввели, скажем, "753" то это и станет значением переменной "x". Одна команда "read" может прочитать (присвоить) значения сразу для нескольких переменных. Если переменных в "read" больше, чем их введено (через пробелы), оставшимся присваивается пустая строка. Если передаваемых значений больше, чем переменных в команде "read", то лишние игнорируются. При обращении к shell-переменной необходимо перед именем ставить символ "$". Так команды echo $var_2 echo var_2 выдадут на экран

ОС UNIX var_2 Экранирование

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

X=22 y=33 z=$x A="$x" B="$x" C=\$x D="$x + $y + $z" E="$x + $y + $z" F=$x\ +\ $y\ +\ $z

(присваивание G=$x+$y не было бы выполнено из-за пробелов) Тогда

Echo A = $A B = $B C = $C echo D = $D E = $E F = $F eval echo evaluated A = $A eval echo evaluated B = $B eval echo evaluated C = $C

Выдадут на экран

A = 22 B = $x C = $x D = 22 + 33 + 22 E = $x + $y + $z F = 22 + 33 + 22 evaluated A = 22 evaluated B = 22 evaluated C = 22

Приведем еще примеры, связанные с экранированием перевода строки. Пусть переменной "string" присвоено значение "массива" 2x3: abc def Обратим внимание, что для избежания присваивания лишних пробелов вторая строка массива начата с первой позиции следующей строки: string="abc def" Тогда три варианта записи переменной в команде "echo" echo $string echo "$string" echo "$string" дадут соответственно три различных результата: abc def $string abc def а последовательность команд echo "str_1 str_2" > file_1 echo "str_1 str_2" > file_2 cat file_1 file_2 даст выдаст последовательно одинаковые файлы file_1 и file_2: str_1 str_2 str_1 str_2 Заметим также, что бэк-слэш (\) не только экранирует следующий за ним символ, что позволяет использовать специальные символы просто как символы, представляющие сами себя (он может экранировать и сам себя - \\), но в командном файле бэк-слэш позволяет об"единять строки в одну (экранировать конец строки). Например, приводившийся ранее пример командной строки:

Cat file_1 | grep -h result | sort | cat -b > file_2

может быть записан в командном файле, скажем, как

Cat file_1 | grep -h \ result | sort | cat -b > file_2

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

Cat file_1 | grep -h result | sort | cat -b > file_2

Манипуляции с shell-переменными Несмотря на то, что shell-переменные в общем случае воспринимаются как строки, т. е. "35" - это не число, а строка из двух символов "3" и "5", в раде случаев они могут интерпретироваться иначе, например, как целые числа. Разнообразные возможности имеет команда "expr". Проиллюстрируем некоторые на примерах: Выполнение командного файла:

X=7 y=2 a=`expr $x + $y` ; echo a=$a a=`expr $a + 1` ; echo a=$a b=`expr $y - $x` ; echo b=$b c=`expr $x "*" $y` ; echo c=$c d=`expr $x / $y` ; echo d=$d e=`expr $x % $y` ; echo e=$e

выдаст на экран

A=9 a=10 b=-5 c=14 d=3 e=1

Операция умножения ("*") обязательно должна быть заэкранирована, поскольку в shell этот значок воспринимается, как спецсимвол, означающий, что на это место может быть подставлена любая последовательность символов. С командой "expr" возможны не только (целочисленные) арифметические операции, но и строковые:

A=`expr "cocktail" : "cock"` ; echo $A B=`expr "cocktail" : "tail"` ; echo $B C=`expr "cocktail" : "cook"` ; echo $C D=`expr "cock" : "cocktail"` ; echo $D

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

4 0 0 0

Экспорт переменных В ОС UNIX существует понятие процесса. Процесс возникает тогда, когда запускается на выполнение какая-либо команда. Например, при наборе на клавиатуре "р " порождается процесс "р". В свою очередь "р" может породить другие процессы. Допустим, что "р" вызывает "р1" и "р2", которые последовательно порождают соответствующие процессы. У каждого процесса есть своя среда - множество доступных ему переменных. Например, до запуска "р" уже существовала среда, в которой уже были определены некоторые переменные. Запуск "р" порождает новую среду; уже в ней будут порождены "р1" и "р2". Переменные локальны в рамках процесса, в котором они объявлены, т.е. где им присвоены значения. Для того, чтобы они были доступны и другим порождаемым процессам, надо передать их явным образом. Для этого используется встроенная команда "export".

Параметры

В командный файл могут быть переданы параметры. В shell используются позиционные параметры (т.е. существенна очередность их следования). В командном файле соответствующие параметрам переменные (аналогично shell-переменным) начинаются с символа "$", а далее следует одна из цифр от 0 до 9: Пусть "examp-1" вызывается с параметрами "cock" и "tail". Эти параметры попадают в новую среду под стандартными именами "1" и "2". В (стандартной) переменной с именем "0" будет храниться имя вызванного расчета. При обращении к параметрам перед цифрой ставится символ доллара "$" (как и при обращении к переменным): $0 соответствует имени данного командного файла; $1 первый по порядку параметр; $2 второй параметр и т.д. Поскольку число переменных, в которые могут передаваться параметры, ограничено одной цифрой, т.е. 9-ю ("0", как уже отмечалось имеет особый смысл), то для передачи большего числа параметров используется специальная команда "shift". Своеобразный подход к параметрам дает команда "set". Например, фрагмент

Set a b с echo первый=$1 второй=$2 третий=$3

выдаст на экран

Первый=a второй=b третий=c

т.е. команда "set" устанавливает значения параметров. Это бывает очень удобно. Например, команда "date" выдает на экран текущую дату, скажем, "Mon May 01 12:15:10 2000", состоящую из пяти слов, тогда

Set `date` echo $1 $3 $5

выдаст на экран

Mon 01 2000

Команда "set" позволяет также осуществлять контроль выполнения программы, например: set -v на терминал выводятся строки, читаемые shell. set +v отменяет предыдущий режим. set -x на терминал выводятся команды перед выполнением. set +x отменяет предыдущий режим. Команда "set" без параметров выводит на терминал состояние программной среды.

Подстановки shell-интерпретатора

Перед началом непосредственной интерпретации и выполнением команд, содержащихся в командных файлах, shell выполняет различные виды подстановок: 1. ПОДСТАНОВКА РЕЗУЛЬТАТОВ. Выполняются все команды, заключенные в обратные кавычки, и на их место подставляется результат. 2. ПОДСТАНОВКА ЗНАЧЕНИЙ ПАРАМЕТРОВ И ПЕРЕМЕННЫХ. То есть слова, начинающиеся на "$", заменяются соответствующими значениями переменных и параметров. 3. ИНТЕРПРЕТАЦИЯ ПРОБЕЛОВ. Заэкранированные пробелы игнорируются. 4. ГЕНЕРАЦИЯ ИМЕН ФАЙЛОВ. Проверяются слова на наличие в них спецсимволов ("*", "?","") и выполняются соответствующие генерации. Программная среда Каждый процесс имеет среду, в которой он выполняется. Shell использует ряд переменных этой среды. Если вы наберете команду "set" без параметров, то на экран будет выдана информация о ряде стандартных переменных, созданных при входе в систему (и передаваемых далее всем вашим новым процессам "по наследству"), а также переменных, созданных и экспортируемых вашими процессами. Конкретный вид и содержание выдаваемой информации в немалой степени зависит от того, какая версия UNIX используется и как инсталлирована система.

Результат выполнения команды set без параметров (не полный):

HOME=/root PATH=/usr/local/bin:/usr/bin:/bin:.:/usr/bin/X11: IFS= LOGNAME=sae MAIL=/var/spool/mail/sae PWD=/home/sae/STUDY/SHELL PS1=${PWD}:" " PS2=> SHELL=/bin/bash

Прокомментируем значения переменных. HOME=/root - это имя домашнего директория, в котором пользователь оказывается после входа в систему. То есть, правильно набрав имя и пароль, я окажусь в директории "/root". PATH=/bin:/usr/bin:.:/usr/local/bin:/usr/bin/X11 - эта переменная задает последовательность файлов, которые просматривает "shell" в поисках команды. Имена файлов разделяются здесь двоеточиями. Последовательность просмотра соответствует очередности следования имен в тропе. Но первоначально поиск происходит среди так называемых встроенных команд. В число встроенных команд входят наиболее часто используемые команды, например "echo", "cd", "pwd", "date". После этого система просматривает директорий "/bin", в котором могут находиться команды "sh", "cp", "mv", "ls" и т.п. Затем директорий "/usr/bin" с командами "cat", "сс", "expr", "nroff", "man" и многими другими. Далее поиск происходит в текущем директории (".", или другое обозначение "пусто", т.е.""), где скорее всего находятся написанные вами команды. После набора командной строки и нажатия "shell" (после выполнения необходимых подстановок) распознает имя, соответствующее команде и осуществляет ее поиск в директориях, перечисленных в PATH. Если команда размещена вне этих директориев, она не будет найдена. Если присутствует несколько команд с одинаковым именем, то вызвана будет та, которая расположена в директории, просматриваемом первым. PATH, как и прочие переменные, можно легко менять, добавляя, переставляя или исключая директории. IFS= (Внутренний Разделитель Полей) перечисляет символы, которые служат для разделения слов (полей). Таковыми являются "пробел", "табуляция" и "перевод строки", поэтому здесь слева от присваивания ничего не видно и занято две строки. LOGNAME=root - имя входа ("имя" пользователя). MAIL=/var/spool/mail/root - имя файла, в который поступает (электронная) почта. PWD=/root - имя текущего директория PS1=${PWD}:" " - вид промтера. В данном случае в промптере будет выдаваться имя текущего директория двоеточие и пробел. То есть здесь будет "/root: ". PS2=> - этот промтер (здесь ">") используется как приглашение к продолжению ввода (в очередной строке) незаконченной команды. Например, наберите открывающую скобку "(" и после нажатия в следующей строке вы увидите этот промптер. Если пока не знаете, что дальше делать, наберите закрывающую скобку ")" и он исчезнет. SHELL=/bin/sh - эта переменная указывает оболочку, которую использует пользователь. В данном случае используется стандартный shell ("sh"). Исходная среда устанавливается автоматически при входе в систему с использованием файлов типа "/etc/rc" и "/etc/.profile". Один из способов просто изменит среду (например, тропу поиска команд, вид промтера, вид оболочки, цвет экрана и т.п.) можно, разместив эту информацию в своем домашнем директории в специализированном файле ".profile" (${HOME}/.profile), присвоив нужные значения переменным среды. То есть вызвать это файл в редактор и написать, что пожелаете). Тогда при каждом вашем входе в систему этот файл будет автоматически выполняться и устанавливать новую среду. Этот файл должен ОБЯЗАТЕЛЬНО размещаться в вашем ДОМАШНЕМ директории (директории входа). Следует иметь в виду, что имена файлов, начинающиеся с точки, вообще имеют особый статус. Так, они не выдаются на экран простой командой "ls" - необходимо вызывать эту команду с флагом "-a". Кстати, и не уничтожаются огульно командой "rm *". Сам интерпретатор shell автоматически присваивает значения следующим переменным (параметрам): ? значение, возвращенное последней командой; $ номер процесса; ! номер фонового процесса;

  1. число позиционных параметров, передаваемых в shell;
  • перечень параметров, как одна строка;

@ перечень параметров, как совокупность слов; - флаги, передаваемые в shell. При обращении к этим переменным (т.е при использовании их в командном файле - shell-программе) следует впереди ставить "$". Важную роль при создании уникальных файлов играет специальная переменная "$$", значение которой соответствует номеру процесса, выполняющего данный расчет. Каждый новый расчет, выполняемый компьютером, инициирует один или несколько процессов, автоматически получающих номера по порядку. Поэтому, используя номер процесса в качестве имени файла, можно быть уверенным, что каждый новый файл будет иметь новое имя (не запишется на место уже существующего). Достоинство является и главным недостатком такого способа именования файлов. Неизвестно, какие имена будут присвоены файлам. И, если в рамках данного процесса можно найти файл "не глядя", т.е., обратившись к нему, используя $$, то потом такие файлы можно легко потерять. Это создает дополнительные проблемы при отладке программ. Вызов интерпритатора Вслед за регистрацией пользователя в системе (с помощью команды login) вызывается интерпретатор языка SHELL. Если регистрационный справочник пользователя содержит файл.profile, то прежде чем с терминала будет принята хотя бы одна команда, интерпретатор выполняет этот файл (подразумевается, что файл.profile содержит команды). При вызове могут указываться следующие ключи: -c строка Команды считываются из заданной строки. -s Команды читаются из стандартного файла ввода. Сообщения интерпретатора записываются в стандартный файл диагностик. -i Интерактивный режим работы. Если первым символом параметра "0" является знак -, то команды считываются из файла.profile.

ПРОГРАММНЫЕ СТРУКТУРЫ===

Как во всяком языке программирования в тексте на языке shell могут быть комментарии. Для этого используется символ "#". Все, что находится в строке (в командном файле) левее этого символа, воспринимается интерпретатором как комментарий. Например,

# Это комментарий.

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

Команда test ("")

Команда test проверяет выполнение некоторого условия. С использованием этой (встроенной) команды формируются операторы выбора и цикла языка shell. Два возможных формата команды:

Test условие

[ условие ]

мы будем пользоваться вторым вариантом, т.е. вместо того, чтобы писать перед условием слово "test", будем заключать условие в скобки, что более привычно для программистов. На самом деле shell будет распознавать эту команду по открывающей скобке "[", как слову, соответствующему команде "test". Между скобками и содержащимся в них условием обязательно должны быть пробелы. Пробелы должны быть и между значениями и символом сравнения или операции В shell используются условия различных "типов". УСЛОВИЯ ПРОВЕРКИ ФАЙЛОВ: -f file файл "file" является обычным файлом; -d file файл "file" - каталог; -с file файл "file" - специальный файл; -r file имеется разрешение на чтение файла "file"; -w file имеется разрешение на запись в файл "file"; -s file файл "file" не пустой.

УСЛОВИЯ ПРОВЕРКИ СТРОК: str1 = str2 строки "str1" и "str2" совпадают; str1 != str2 строки "str1" и "str2" не совпадают; -n str1 строка "str1" существует (непустая); -z str1 строка "str1" не существует (пустая). Примеры.

X="who is who"; export x; [ "who is who" = "$x" ]; echo $? 0 x=abc ; export x ; [ abc = "$x" ] ; echo $? 0 x=abc ; export x ; [ -n "$x" ] ; echo $? 0 x="" ; export x ; [ -n "$x" ] ; echo $? 1

Кроме того, существуют два стандартных значения условия, которые могут использоваться вместо условия (для этого не нужны скобки). УСЛОВИЯ СРАВНЕНИЯ ЦЕЛЫХ ЧИСЕЛ: x -eq y "x" равно "y", x -ne y "x" неравно "y", x -gt y "x" больше "y", x -ge y "x" больше или равно "y", x -lt y "x" меньше "y", x -le y "x" меньше или равно "y". СЛОЖНЫЕ УСЛОВИЯ: Реализуются с помощью типовых логических операций: ! (not) инвертирует значение кода завершения. -o (or) соответствует логическому "ИЛИ". -a (and) соответствует логическому "И".

Условный оператор "if"

В общем случае оператор "if" имеет структуру

If условие then список

Здесь "elif" сокращенный вариант от "else if" может быть использован наряду с полным, т.е. допускается вложение произвольного числа операторов "if" (как и других операторов). Разумеется "список" в каждом случае должен быть осмысленный и допустимый в данном контексте. Самая усеченная структура этого оператора

If условие then список fi

если выполнено условие (как правило это ком получен код завершения "0", то выполняется "список", иначе он пропускается. Примеры. Пусть написан "if-1"

If [ $1 -gt $2 ]

then pwd else echo $0: Hello!

Тогда вызов if-1 12 11 даст /home/sae/STUDY/SHELL а if-1 12 13 даст if-1: Hello!

Оператор вызова ("case")

Оператор выбора "case" имеет структуру:

Case строка in

шаблон) список команд;; шаблон) список команд;; ... шаблон) список команд;;

Здесь "case" "in" и "esac" - служебные слова. "Строка" (это может быть и один символ) сравнивается с "шаблоном". Затем выполняется "список команд" выбранной строки. Непривычно выглядят в конце строк выбора ";;", но написать здесь ";" было бы ошибкой. Для каждой альтернативы может быть выполнено несколько команд. Если эти команды будут записаны в одну строку, то символ ";" будет использоваться как разделитель команд. Обычно последняя строка выбора имеет шаблон "*", что в структуре "case" означает "любое значение". Эта строка выбирается, если не произошло совпадение значения переменной (здесь $z) ни с одним из ранее записанных шаблонов, ограниченных скобкой ")". Значения просматриваются в порядке записи.

Оператор цикла с перечислением ("for")

Оператор цикла "for" имеет структуру:

For имя

do список команд done где "for" - служебное слово определяющее тип цикла, "do" и "done" - служебные слова, выделяющие тело цикла. Пусть команда "lsort" представлена командным файлом

For i in file_1 file_2 file_3 do proc_sort $i done

В этом примере имя "i" играет роль параметра цикла. Это имя можно рассматривать как shell-переменную, которой последовательно присваиваются перечисленные значения (i=file_1, i=file_2, i=file_3), и выполняется в цикле команда "proc_sort". Часто используется форма "for i in *", означающая "для всех файлов текущего каталога". Пусть "proc_sort" в свою очередь представляется командным файлом

Cat $1 | sort | tee /dev/lp > ${1}_sorted

т.е. последовательно сортируются указанные файлы, результаты сортировки выводятся на печать ("/dev/lp") и направляются в файлы file_1_sorted file_2_sorted и file_3_sorted

Оператор цикла с истинным условием ("while")

Структура "while", также обеспечивающая выполнение расчетов, предпочтительнее тогда, когда неизвестен заранее точный список значений параметров или этот список должен быть получен в результате вычислений в цикле. Оператор цикла "while" имеет структуру:

While условие

do список команд done где "while" - служебное слово определяющее тип цикла с истинным условием. Список команд в теле цикла (между "do" и "done") повторяется до тех пор, пока сохраняется истинность условия (т.е. код завершения последней команды в теле цикла равен "0") или цикл не будет прерван изнутри специальными командами ("break", "continue" или "exit"). При первом входе в цикл условие должно выполняться. Команда "break [n]" позволяет выходить из цикла. Если "n" отсутствует, то это эквивалентно "break 1". "n" указывает число вложенных циклов, из которых надо выйти, например, "break 3" - выход из трех вложенных циклов. В отличие от команды "break" команда "continue [n]" лишь прекращает выполнение текущего цикла и возвращает на НАЧАЛО цикла. Она также может быть с параметром. Например, "continue 2" означает выход на начало второго (если считать из глубины) вложенного цикла. Команда "exit [n]" позволяет выйти вообще из процедуры с кодом возврата "0" или "n" (если параметр "n" указан). Эта команда может использоваться не только в циклах. Даже в линейной последовательности команд она может быть полезна при отладке, чтобы прекратит выполнение (текущего) расчета в заданной точке.

Оператор цикла с ложным условием ("until")

Оператор цикла "until" имеет структуру:

Until условие

do список команд done где "until" - служебное слово определяющее тип цикла с ложным условием. Список команд в теле цикла (между "do" и "done") повторяется до тех пор, пока сохраняется ложность условия или цикл не будет прерван изнутри специальными командами ("break", "continue" или "exit"). При первом входе в цикл условие не должно выполняться. Отличие от оператора "while" состоит в том, что условие цикла проверяется на ложность (на ненулевой код завершения последней команды тела цикла) проверяется ПОСЛЕ каждого (в том числе и первого!) выполнения команд тела цикла. Пример.

Until false do

read x if [ $x = 5 ] then echo enough ; break else echo some more fi

Здесь программа с бесконечным циклом ждет ввода слов (повторяя на экране фразу "some more"), пока не будет введено "5". После этого выдается "enough" и команда "break" прекращает выполнение цикла.

Пустой оператор

Пустой оператор имеет формат

:

Ничего не делает. Возвращает значение "0".".

Функции в shell

Функция позволяет подготовить список команд shell для последующего выполнения. Описание функции имеет вид:

Имя() { список команд }

после чего обращение к функции происходит по имени. При выполнении функции не создается нового процесса. Она выполняется в среде соответствующего процесса. Аргументы функции становятся ее позиционными параметрами; имя функции - ее нулевой параметр. Прервать выполнение функции можно оператором "return [n]", где (необязательное) "n" - код возврата.

Обработка прерываний ("trap")

Бывает необходимо защитить выполнение программы от прерывания. Наиболее часто приходится встречаться со следующими прерываниями, соответствующими сигналам: 0 выход из интерпретатора, 1 отбой (отключение удаленного абонента), 2 прерывание от , 9 уничтожение (не перехватывается), 15 окончание выполнения. Для защиты от прерываний существует команда "trap", имеющая формат:

Trap "список команд" сигналы

Если в системе возникнут прерывания, чьи сигналы перечислены через пробел в "сигналы", то будет выполнен "список команд", после чего (если в списке команд не была выполнена команда "exit") управление вернется в точку прерывания и продолжится выполнение командного файла. Например, если перед прекращением по прерываниям выполнения какого то командного файла необходимо удалить файлы в "/tmp", то это может быть выполнено командой "trap":

Trap "rm /tmp/* ; exit 1" 1 2 15

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

В этой статье постараемся собрать наиболее часто используемые команды в SSH или linux shell. Список не является окончательным, описание команд естественно не полное, полное описание команд Вы можете получить в linux shell# man command.



Горячие комбинации клавиш и Команды Linux:

ВНИМАНИЕ: ПОМНИТЕ ЧТО КОМАНДЫ LINUX ЧУСТИТЕЛЬНЫ К РЕГИСТРУ, В КОТОРОМ ИХ НАБИРАЮТ. Например: Команды Netscape, NETSCAPE и nEtscape это три различные команды, точно также my_filE, my_file, и my_FILE это три различных файла.

1. Естественные сочетания клавиш и обозначения
Переключение на первый консольный терминал
Переключение на #ый консольный терминал (#=1..6)
Переключение на графический терминал (если таковой запущен)
Дополнение текущей последовательности символов, набранной в консоли, до исполняемой команды. Эта особенность сильно облегчает жизнь при наборе команд! Это работает также и при загрузке компьютера через LILO!
Просмотр и редактирование буфера истории команд. Для исполнения команды нажмите .
Просмотр текста выведенного на консольный терминал и ушедшего за приделы экрана. Перемещение в вверх.
То же что и выше. Перемещение в вниз.
[+] (в X-windows) Изменение разрешения. Переключение к следующей конфигурации.
[-] (В X-windows) Изменение разрешения. Возврат к предыдущей конфигурации.
(в X-windows) Убить текущий сервер X-windows (выйти из графической оболочки, уничтожив все процессы). Убить текущий процесс.
d Выход из текущего терминала (обычно работает).
d Посылка текущему процессу сигнала [Конец-файла] (конец файла).
s Остановка вывода на терминал.
q Возобновление вывода на терминал. Попробуйте эту комбинацию клавиш, если ваш терминал непонятно почему перестал отвечать на ваши запросы.
z Послать текущий процесс в background.
reset Восстановление значений по умолчанию для "запорченного" терминала (терминал показывает странные символы и неадекватно реагирует на нажатие клавиш). Используйте эту команду если вы попытались вывести на экран бинарный файл. Вероятно вы не сможете увидеть эту команду в процессе ее набора.
~ Моя домашняя директория. Например cd ~/моя_поддиректория.
. (точка) Текущая директория.
.. (две точки) Родительская директория для текущего каталога.

2. Стандартные команды и команды, дающие информацию по системе
pwd Вывести текущую директорию.
hostname Вывести или изменить сетевое имя машины.
whoami Ввести имя под которым я зарегистрирован.
date Вывести или изменить дату и время. Например, чтобы установить дату и время равную 2000-12-31 23:57, следует выполнить команду: date 123123572000
time Получить информацию о времени, нужного для выполнения процесса + еще кое-какую информацию. Не путайте эту команду с date. Например: Я могу определить как много времени требуется для вывода списка файлов в директории, набрав последовательность: time ls
who Определить кто из пользователей работает на машине.
rwho -a Определение всех пользователей, подключившихся к вашей сети. Для выполнения этой команды требуется, чтобы был запущен процесс rwho. Если такого нет - запустите "setup" под суперпользователем.
finger [имя_пользователя] Системная информация о зарегистрированном пользователе. Попробуйте: finger root
uptime Количество времени прошедшего с последней перезагрузки.
ps a Список текущих процессов.
top Интерактивный список текущих процессов отсортированных по использованию cpu.
uname Вывести системную информацию.
free Вывести информацию по памяти.
df -h (=место на диске) Вывести информацию о свободном и используемом месте на дисках (в читабельном виде).
du / -bh | more (=кто сколько занял) Вывод детальной информации о размере файлов по директориям начиная с корневой (в читабельном виде).
cat /proc/cpuinfo Системная информация о процессоре. Заметьте, что файла в /proc директории - не настоящие файлы. Они используются для получения информации, известной системе.
cat /proc/interrupts Используемые прерывания.
cat /proc/version Версия ядра Linux и другая информация
cat /proc/filesystems Вывести используемые в данный момент типы файловых систем.
cat /etc/printcap Вывести настройки принтера.
lsmod (как root) Вывести информацию о загруженных в данный момент модулях ядра.
set|more Вывести текущие значения переменных окружения.
echo $PATH Вывести значение переменной окружения "PATH" Эта команда может использоваться для вывода значений других переменных окружения. Воспользуйтесь командой set, для получения полного списка.

3. Работа с сетью
netconf (как root) Очень хорошая программа настройки сети, использующая для интерактивной работы с пользованием, текстовое меню.
ping [имя_машины] "Проверка на вшивость". Есть или нет контакта с другой машиной (в качестве параметре команде можно передавать сетевое имя машины или IP адрес), нажмите -C когда вся требуемая информация будет получена.
route -n Вывести таблицу маршрутизации (the routing table).
ipfwadm -F -p m Настроить firewall.
ifconfig (как root) Вывести информацию о текущих сетевых интерфейсах (ethernet, ppp, и т.д.) Ваша первая ethernet плата плата будет показана как eth0, вторая как eth1, первый ppp модем как ppp0 и так далее. "lo" - расшифровывается как "loopback only" сетевой интерфейс, который должен быть постоянно активирован. Используйте соответствующие опции (смотрите результат выполнения ifconfig --help) для настройки сетевых интерфейсов.
ifup [имя_сетевого_интерфейса] (/sbin/ifup при работе под обычным пользователем) Активизация соответствующего сетевого интерфейса. Например: ifup eth0 ifup ppp0. Пользователь может активизировать и выключить сетевое интерфейс ppp только когда установлены соответствующие права доступа (права можно установить в процессе настройки ppp через "netconf")
ifdown [имя_сетевого_интерфейса] (/sbin/ifdown при работе под обычным пользователем). Диактивизация соответствующего сетевого интерфейса.

4. Простейшие действия
ls Список файлов в текущей директории. Команда выполнении команды dir выполняется команда ls.
cd [директория] Сменить директорию.
cp [что копировать][куда копировать] Копировать файлы.
mcopy [что копировать][куда копировать] Копировать файлы при работе с файловой системой dos (монтировать диска dos необязательно). Например: mcopy a:\autoexec.bat ~/junk . Для дополнительной информацией по подобным командам (mdir, mcd, mren, mmove, mdel, mmd, mrd, mformat ....) ознакомьтесь с man mtools.
mv [что перемещать][куда перемещать] Переместить или переименовать файл.
ln -s [на что сделать ссылку][имя ссылки] Создать символическую ссылку.
rm [файлы] Удалить файлы.
mkdir [директорию] Создать новую директорию.
rmdir [директорию] Удалить пустую директорию.
rm -r [файлы и/или директории] (рекурсивное удаление) Удалить файлы, директории и их поддиректории. ОСТОРОЖНЕЙ с этой командой, если у вас права суперпользователя! Пока у Linux нет системы полного восстановления удаленных файлов (если вы не пользуетесь специальными программами для помещения удаленный файлы в специальный каталог - a la корзинка под W95).
cat [имя файла] | more Просмотр содержимого текстового файла по одной странице за раз.
less [имя файла] Просмотр содержимого текстового файла с возможностью вернуться к предыдущим страницам. Нажмите q когда захотите выйти из программы. "Less" - аналог команды DOS "more", хотя очень часто "less" бывает более удобной чем "more".
pico [имя файла] Редактировать текстовый файл.
lynx Просмотр файла html или WWW ссылки с помощью текстового браузера Lynx.
tar -zxvf [файлы] Распаковать архив tgz или tar.gz, который вы вытянули из сети.
find / -name "имя файла" Найти файл с именем "имя файла". Поиск начинается с директории / . "имя файла" может содержать маску для поиска.
pine Хорошая текстово - ориентированная программа для чтения электронной почты. Еще одна подобная программа называется "elm". Netscape считывает ваши письма с вашего Internet адреса, а pine позволяет вам просматривать "локальную" почту - то есть ту почту, которую посылает вам процесс son или cron.
mc Запустить программу управления файлами "Midnight Commander" (Выглядит как "Norton Commander", но по своим возможностям ближе к far или dn).
telnet [сервер] Связаться по telnet с другой машиной. Используйте имя машины или ее IP адрес. Войдите с помощью вашего пароля (вы должны быть зарегистрированы на этой удаленной машине). Это позволит вам войти на другую машину и работать на ней, как будто вы сидите за ее клавиатурой (почти никаких отличий).
ftp [сервер] Связаться по ftp с удаленным компьютером. Этот тип связи хорош для копирования файлов с/на удаленную машину.

5. Основные Команды Администрирования
printtool (как root в X терминале) Сконфигурировать ваш принтер.
setup (как root) Сконфигурировать мышь, звуковую карту, клавиатуру, графическую оболочку X-windows и системные службы. Очень простая в пользовании программа.
alias ls="ls -Fskb --color" Создать alias - псевдоним для того чтобы одной командой можно было запустить более сложную комбинацию команд. Поместите создание alias в файл /etc/bashrc если вы хотите, чтобы эти псевдонимы были доступны всем пользователям вашей системы.
adduser [имя_пользователя] Зарегистрировать нового пользователя (у вас должны быть права суперюзера). Например: adduser ivanov . Не забудьте следующим делом настроить пароль пользователя. Директория пользователя находится в каталоге /home/имя_пользователя.
useradd [имя_пользователя] То же, что и adduser.
userdel [имя_пользователя] Удалить пользователя из системы (вы должны зайти как root). С пользовательским каталогом и не прочитанными письмами удаленного пользователя нужно разбираться отдельно.
groupadd [имя_группы] Создать новую группу пользователей на вашей системе. Не обязательно создавать группу непосредственно на основной машине.
passwd Изменить пароль. Если вы суперпользователь, то вы можете изменить пароль любого зарегистрированного пользователя набрав команду: passwd имя_пользователя
chmod [права доступа][файл] (=change mode) Изменить права доступа файлов, чьим владельцем вы являетесь (если вы root, в этом случае вы можете изменить права доступа для любого файла). Есть три способа доступа к файлу: чтение - read (r), запись - write (w), исполнение - execute (x) и три типа пользователей: хозяин файла - owner (u), члены той же группы, что и хозяин файла (g) и все остальные (o). Поверить текущие права доступа можно следующим способом: ls -l имя_файла . Если файл доступен всеми способами всем пользователям, то напротив имени файла будет следующая комбинация букв: rwxrwxrwx . Первые три буквы - это права доступа для хозяина/хозяйки файла, второй триплет - права доступа для его/ее группы, следующая тройка - права доступа для остальных. Отсутствие права доступа показывается как "-".; Например: Эта команда позволит вам установить права доступа на чтение для файла "junk" для всех (all=user+group+others):
chmod a+r junk
Эта команда отнимет право доступа на исполнение файла у всех кроме пользователя и группы:
chmod o-x junk
Для получение дополнительной информации наберите chmod --help или man chmod или почитайте любое руководство по Linux.
Вы можете установить права доступа по умолчанию для создаваемых вами файлов с помощью команды "umask" (наберите man umask).
chown [новый_хозяин][файлы]
chgrp [новая_группа][файлы] Изменить хозяина и группу для файла.
Вы можете использовать эти две команды, после того как сделали копию файла для кого- либо. su (=super user) Вход в систему как суперпользователь (у вас спросят ваш пароль). Набрав "exit" вы вернетесь в вашу предыдущую пользовательскую оболочку. Пользователь root существует для администрирования системы и команда su дает быстрый доступ к возможностям суперпользователя, когда вам это потребуется. Никогда не входите в систему под пользователем root, используйте для этой цели команду su.

6. Контроль процессов
ps (=print status) Вывести список текущих процессов с их IDs (PID) идентификаторами. Используйте ps axu для того чтобы отобразить все процессы запущенные на вашей системе, которые имеют вас в качестве хозяина (это касается и процессов которые отцеплены от терминала).
fg Вернуть фоновый или приостановленный процесс в интерактивное (высокоприоритетное) состояние;
bg Сделать процесс фоновым. Обратная функция от fg. Может следовать вслед за комбинацией z.
kill "Убить" процесс. Для начала определите PID "убиваемого" процесса при помощи ps.
killall [имя_программы] "Убить" все процессы по имени программы.
lpc (как root) Проверить очередь принтера.
lpq Вывести список очереди заданий на печать.
lprm [Номер Задание] Удалить задание из очереди на печать.
nice [имя_программы] Запустить процесс, установив его приоритет.
renice Изменить приоритет процесса.

Обратите внимание на комбинации клавиш: c, z, s, и q. Они описаны ранее в разделе Естественные сочетания клавиш и обозначения.

Что такое shell и зачем он нужен

Командная оболочка в любых unix-подобных системах, к которым относится и GNU/Linux, является обычной программой, запускаемой как в текстовой консоли (которая используется всё реже), так и в графической среде – в окне эмулятора терминала, доступного в любой Linux-системе.

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

Почти во всех дистрибутивах Linux для пользователей по умолчанию назначается командная оболочка bash (Bourne Again SHell – ещё одна командная оболочка Бурна; Стив Бурн – автор первой командной оболочки в Unix – sh). Фактически она стала неофициальным стандартом, и усовершенствование ее функциональных возможностей продолжается непрерывно. Существуют и другие командные оболочки – tcsh (версия C-shell), ksh (Korn Shell), zsh и т.д. – у каждой есть свои достоинства и недостатки, а также свои группы поклонников. Тем не менее, bash более привычна широким массам пользователей с различными уровнями подготовки, потому я и остановил свой выбор на ней. Стоит также отметить, что какими бы возможностями ни обладали различные оболочки, все они совместимы со своим идеологическим прародителем – Bourn Shell (sh). Иными словами, скрипт, написанный для sh, будет корректно работать в любой современной оболочке (обратно, вообще говоря, неверно).

Преимущества командной строки

Может возникнуть вопрос: зачем возиться с командной строкой, если существуют удобные и красивые графические интерфейсы? Тому есть множество причин. Во-первых, далеко не все операции удобнее и быстрее выполнять с помощью графического интерфейса. Во-вторых, каждая программа следует основополагающему принципу Unix-систем: делать чётко определённую работу и делать её хорошо. Иными словами, вы всегда понимаете, что происходит при запуске той или иной утилиты (если что-то не вполне понятно, то следует обратиться к man-руководству). В-третьих, осваивая команды, пробуя их сочетания и комбинации их параметров, пользователь изучает систему, приобретая ценный практический опыт. Вы получаете доступ к таким эффективным инструментам, как конвейеры, позволяющие организовать цепочку команд для обработки данных, средства перенаправления ввода/вывода, а кроме того, можете программировать непосредственно в командной оболочке. Пожалуй, на программировании стоит остановиться подробнее, тем более что многие системные сценарии в Linux (например, скрипты запуска системных сервисов) написаны для shell.

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

Итак, командную оболочку можно рассматривать как язык программирования и как программную среду выполнения одновременно. Разумеется, этот язык не компилируемый, а интерпретируемый. Он допускает использование переменных: системных или собственных. Последовательность выполнения команд программы изменяется с помощью конструкций проверки условия и выбора соответствующего варианта: if-then-else и case. Циклы while, until и for позволяют автоматизировать многократно повторяющиеся действия. Имеется возможность объединять группы команд в логические блоки. Вы можете даже писать настоящие функции с передачей в них параметров. Таким образом, налицо все признаки и характеристики полноценного языка программирования. Попробуем извлечь из этого двойную пользу – наряду с изучением основ программирования автоматизируем свою повседневную работу.

Hello, World! Простая система резервного копирования

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

#!/bin/bash # # Резервное копирование каталогов и файлов из домашнего каталога # Этот командный скрипт можно автоматически запускать при помощи cron # cd $HOME if [ ! -d archives ] then mkdir archives fi cur_date=`date +%Y%m%d%H%M` if [ $# -eq 0 ] ; then tar czf archive${cur_date}.tar.gz projects bin else tar czf archive${cur_date}.tar.gz $* fi if [ $? = 0 ] ; then mv archive${cur_date}.tar.gz $HOME/archives echo "$cur_date – Резервное копирование успешно завершено." else echo "$cur_date – ОШИБКА во время резервного копирования." fi

Любой командный сценарий (script – скрипт, так называются программы командной оболочки) начинается со строки идентификатора, в которой явно задаётся интерпретатор команд с указанием полного пути к нему. Полный путь – последовательное перечисление всех каталогов, начиная с корневого, в которые надо войти, чтобы добраться до целевого файла, и, разумеется, имя этого файла. Запись полного пути чрезвычайно важна для однозначной идентификации каждого файла в иерархии файловой системы.

Далее следуют четыре строки комментариев. Как только командная оболочка встречает символ "#", она считает все последующие символы комментариями и полностью игнорирует их до конца текущей строки. Поэтому комментарий можно начать не с самого начала строки, а сопроводить им какую-либо команду.

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

Наконец-то мы добрались до первой «настоящей» команды. Она позволяет сменить каталог (Change Directory), т.е. перейти из текущего каталога в другой, переданный команде как аргумент. В большинстве случаев целевой каталог задаётся в явной форме, например, cd /tmp или cd projects, но в нашем случае используется предопределённая системная переменная HOME – в ней содержится полный путь к домашнему каталогу текущего пользователя, от имени которого выполняется командный сценарий. Тем самым мы избавляемся от необходимости вносить изменения в код всякий раз при смене пользователя, потому что команда возвращает любого в его личный каталог. Знак доллара "$" перед именем переменной означает, что необходимо извлечь значение, содержащееся в этой переменной, и подставить его в командную строку вместо её имени. Особо следует отметить, что в командном языке оболочки регистров букв имеют важное значение, т.е. HOME, Home и home – это три различные переменные. По соглашению, буквами верхнего регистра обозначаются имена системных переменных: HOME, PATH, EDITOR и т.д. Это соглашение не запрещает пользователям создавать свои переменные с именами из заглавных букв, но зачем усложнять себе жизнь, нарушая общепринятые нормы и правила? Не рекомендуется также изменять значения системных переменных без крайней необходимости. В общем, соблюдаем простое правило: системные переменные используем только для чтения, а если потребовалась собственная, то её имя записываем буквами нижнего регистра.

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

cd ~

Здесь символ "~" также означает домашний каталог текущего пользователя. Ветераны командной строки выражаются ещё лаконичнее:

cd

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

На очереди классическая программная конструкция проверки условия и принятия соответствующего решения. Общая схема такова:

if <условие> then <одна или несколько команд> fi

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

Для проверки условия, как правило, применяется команда test или её альтернативная форма записи в квадратных скобках. Иначе говоря, записи

if [ ! -d archives ] if test ! -d archives

абсолютно равнозначны. Я предпочитаю квадратные скобки, поскольку они более наглядно определяют границы проверяемого условия. И правая, и левая скобка должны быть обязательно отделены от условия пробелами.

Критерии проверки условия определяются разнообразными флагами. Команда test распознаёт очень большой их список. В нашем примере использован флаг -d, позволяющий проверить, соответствует ли заданное после флага имя реально существующему каталогу (directory). Наиболее часто при работе с файлами применяются следующие флаги:

F – существует ли обычный файл с заданным именем;

R – установлено ли для заданного файла право на чтение из него;

W – установлено ли для заданного файла право на запись в него;

X – установлено ли для заданного файла право на его выполнение;

S – имеет ли заданный файл ненулевой размер.

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

if [ ! -d archives ] Если не существует каталог archives (в текущем каталоге), then то начать выполнение блока команд: mkdir archives создать каталог archives (в текущем каталоге) fi завершить выполнение блока команд.

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

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

ten=10 string="Это строка текста"

Но в нашем примере применяется небольшая хитрость. Обратите внимание, что после знака равенства – символа присваивания – записана команда в обратных кавычках. Такая форма записи позволяет присвоить переменной не саму строку, а результат её выполнения. Здесь это вывод команды date, которая возвращает текущую дату и время в формате, определяемом списком параметров:

%Y – текущий год в полной форме, т.е. из четырёх цифр (например, 2009);

%m – номер текущего месяца (например, 09 – для сентября);

%d – номер текущего дня;

%H – текущий час в 24-часовом формате;

%M – текущая минута.

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

cur_date=`date +%Y%m%d%H%M`

десятого сентября 2009 года в 22:45, то переменной cur_date будет присвоено строковое значение "200909102245". Цель этого ухищрения – сформировать уникальное, не повторяющееся имя архивного файла. Если вы намерены запустить несколько экземпляров программы в течение одной минуты, то можете улучшить уникальность имён, добавляя ещё и текущие секунды. Как? Изучите руководство утилиты date (man date) – в этом нет ничего сложного.

Прежде чем приступить к созданию файла архива, необходимо определить, какие именно каталоги мы будем сохранять в нём. Для большей гибкости можно задать набор каталогов, архивируемых по умолчанию, но предусмотреть возможность замены этого набора списком каталогов, передаваемым как аргумент в наш командный сценарий. Для этого используются специальные переменные командной оболочки: $# – число переданных в сценарий параметров и $* – все переданные параметры, записанные в формате одной строки.

if [ $# -eq 0 ] ; then

Проверка условия «если число переданных параметров равно нулю», то выполнить следующую команду. Отметим, что ключевое слово then можно записать в строке условия, отделив его от условного выражения точкой с запятой.

tar czf archive${cur_date}.tar.gz projects bin

Команда создания архивного файла и сжатия этого файла. Сама утилита tar не выполняет сжатие, а только лишь собирает все заданные файлы и каталоги в единый tar-файл. Для этого предназначен первый флаг - c (create – создать). Сжатие выполняет внешняя программа – здесь это gzip, вызываемый вторым флагом - z. Если в вашей системе установлена более эффективная программа сжатия bzip2, то вы можете воспользоваться ею, изменив команду следующим образом:

tar cjf archive${cur_date}.tar.bz2 projects bin

Третий флаг f сообщает о том, что далее следует имя архивного файла, поэтому всегда является замыкающим в перечне флагов. Обратите внимание на то, что при подстановке имя переменной заключено в фигурные скобки. Это сделано, чтобы явно выделить переменную в окружающей её строке, тем самым устраняя многие потенциальные проблемы. Расширения архивному файлу не присваиваются автоматически, вы сами дописываете всё необходимое. В качестве каталогов, архивируемых по умолчанию, я указал projects и bin, но вы можете записать здесь имена своих наиболее ценных каталогов.

Ключевое слово else открывает альтернативную ветвь выполнения. Команды этого блока начинают работать, если проверка условия даёт результат «ложь» (в нашем примере: «число переданных параметров ненулевое», т.е. пользователь задал имена каталогов). В этом случае команда будет выглядеть так:

tar czf archive${cur_date}.tar.gz $*

Здесь каталоги по умолчанию заменены строкой имён каталогов, принятой извне. Имеется возможность принимать и обрабатывать каждый внешний параметр по отдельности, но нам удобнее передать строку целиком.

В конце программы выполняется ещё одна проверка. В unix-средах все команды возвращают код статуса завершения своей работы. Если команда отработала успешно, то она возвращает код 0, в противном случае код завершения будет ненулевым. Чтобы проверить успешность выполнения предыдущей команды архивации, воспользуемся ещё одной специальной переменной $?, в которой всегда содержится значение кода завершения самой последней команды. Если в переменной $? содержится 0, т.е. файл резервной копии был успешно создан, то мы перемещаем его в каталог архивов:

mv archive${cur_date}.tar.gz $HOME/archives

и выдаём соответствующее сообщение:

echo "$cur_date – Резервное копирование успешно завершено."

Если проверка показала, что код завершения операции архивирования не равен нулю, то выводится сообщение об ошибке:

echo "$cur_date – ОШИБКА во время резервного копирования."

На этом работа нашего командного сценария завершается.

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

chmod 750 bckp

и запустить:

./bckp

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

./bckp docs progs works

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

Можно поместить файл bckp в один из каталогов, указанных в системной переменной PATH. Наиболее предпочтительными местами размещения являются /usr/local/bin или $HOME/bin, если таковые у вас имеются. После этого вы можете запускать bckp как системную команду.

Как автоматизировать операции резервного копирования «по расписанию»

Несколько слов об автоматизации резервного копирования. Для этой цели служит системный планировщик cron, который считывает рабочие инструкции из специального crontab-файла. Чтобы определить такие инструкции, необходимо создать и отредактировать свой crontab-файл при помощи команды:

crontab -e

Инструкции записываются в строго определённом формате (поля разделяются пробелами):

минуты часы день_месяца месяц день_недели команда

Один из вариантов расписания операций резервного копирования может выглядеть следующим образом:

30 23 10,20,30 * * /usr/local/bin/bckp

Это означает, что сценарий резервного копирования (следует указать полный путь к этому файлу) будет выполняться в 23:30 10-го, 20-го и 30-го числа каждого месяца независимо от дня недели. (Звёздочки обозначают весь допустимый диапазон значений, в данном случае: каждый месяц – в 4-м поле, любой день недели – в 5-м поле)

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

0 5 * * 3,5 /usr/local/bin/bckp

Здесь резервные копии будут создаваться в 5:00 по средам и пятницам в каждом месяце (звёздочка в 4-м поле), независимо от числа (звёздочка в 3-м поле).

Обо всех тонкостях составления расписания можно прочитать в руководстве man 5 crontab.

Итоги и выводы

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

Ресурсы для скачивания

static.content.url=http://www.сайт/developerworks/js/artrating/

ArticleID=458335

ArticleTitle=Основы программирования в командной оболочке shell

=====================================================

ЛАБОРАТОРНАЯ РАБОТА № 1 (время выполнения -- 3 часа)

Тема: ”Введение в shell

1. Введение в shell

Shell– это интерпретатор команд (командный процессор), осуществляющий функции интерфейса между пользователем и ядром Unix. Solarisпредлагает три основных командных процессора:

    Принятый по умолчанию командный процессор Bourne-- /sbin/sh

    Командный процессор C -- /bin/csh

    Командный процессор Korn-- ./bin/ksh

Кроме перечисленных, Solarisпредоставляет еще дополнительные оболочки:

    J-оболочка -- /sbin/jsh

    Restricted Korn l -- /usr/ bin/rsh

    T-оболочка -- /usr/bin/tcsh

    GNU Bourne Again -- /usr/bin/bash

    Z-оболочка – usr/bin/zsh

Выбор командного процессора является вопросом персональных предпочтений.

2. Запуск команд

Любая команда в Unix состоит из имени запускаемой программы (команды), опций (ключей) и аргументов, передаваемых программе. Разделителем в командной строке является пробелы или знаки табуляции.

Пример

$ /bin/ping –t 10 192.168.2.13

аргумент

приглашение shell

Если при запуске программы не указывается путь к исполняемому файлу, то ОС последовательно просматривает каталоги, задаваемые в переменной PATH. Если в просматриваемом каталоге находится программа с таким именем, то она запускается на выполнение. Текущий рабочий каталог при поиске программ не просматривается, только если он не задан в переменной PATH.

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

Примеры

Запуск программы с указанием полного пути

$ / usr / local / bin / my _ program

Запуск программы из вышестоящего (родительского) каталога

$ ../ local / bin / my _ program

Запуск программы из текущего каталога

$ ./ my _ program

3. Специальные символы в shell

Некоторые символы в shell имеют специальное значение.

3.1. Шаблоны генерации имен файлов

? (вопросительный знак) соответствует любому одному символу, кроме первой точки;

(квадратные скобки) определяют группу символов (выбирается один символ из группы);

- (знак “минус”) определяет диапазон допустимых символов;

! (восклицательный знак) отвергает следующую за ним группу символов;

* (символ “звездочка”) соответствует любому количеству символов, кроме первой точки.

3.2. Символы перенаправления ввода/вывода

< - перенаправление ввода;

>, >> - перенаправление вывода;

2>, 2>> - перенаправление сообщений об ошибках;

| - конвейер.

3.3. Симолы подстановки

$имя_переменно q - подстановка переменных;

$(команда) или `команда` - подстановка команд;

~ - тильда-подстановка.

4. Поиск

Для быстрого поиска файлов и каталогов используется команда whereis, для более глубокого – командаfind(поиск файлов, удовлетворяющих заданным требованиям;).

5. Текстовый редактор vi

Текстовый редактор viявляется универсальным редактором, присутствующим в любом Unix. Кроме редактирования текстовых файлов, редактор vi может использоваться для редактирования командной строки.

Редактор vi имеет 3 режима работы (см.рисунок).

Вход в редактор vi

Выход из vi

Знаком ”~” (тильда) в первой позиции помечаются пустые (несуществующие) строки файла.

Основным режимом является командный, в котором команды вводятся нажатием некоторой последовательности клавиш (на экране никак не отображаются).

Перемещение по тексту в командном режиме осуществляется с помощью стрелок и клавиш (влево), (вниз), (вверх), (вправо).

Некоторые команды vi приведены в таблице.

Удаление текущей строки

Копирование текущей строки в буфер

Yдвижение курсора

Занесение отмеченных курсором символы в буфер

Вставка новой строки снизу

Вставка новой строки сверху

Добавление после курсора

Добавление после текущей строки

Вставка перед курсором

Вставка перед текущей строкой

Замена символа на символ, вводимый с клавиатуры

Вставка текста из буфера

. (точка)

Повтор последней выполненной команды

Отмена последней команды

Отмена всех изменений в текущей строке

Удаление символа над курсором

В режиме ввода все набранные на клавиатуре символы вставляются в текст.

В режиме последней строки вводимая команда отображается в последней строке экрана.

6. Помощь

В Unix имеется электронный справочник, содержащий описание предназначения команд, их синтаксиса, примеры использования и пр. Справочник вызывается командой man:

7. Основные команды shell

who – вывод информации об активных пользователях;

echo – вывод сообщений на терминал;

banner – вывод сообщений на терминал прописными буквами;

man – вызов оперативной справочной системы;

date – вывод текущей даты;

write – передача сообщений на терминал другого пользователя;

mesg – разрешение/запрет вывода сообщений от других пользователей;

mail – отправка/получение почты;

news – знакомство с новостями системы;

pwd – вывод абсолютного маршрутного имени текущего рабочего каталога;

cd – изменение рабочего каталога;

ls – вывод информации о содержимом каталога;

mkdir – создание каталога;

rmdir – удаление каталога;

touch – обновление временной метки файла;

cp – копирование файлов;

cat – объединение и вывод на экран содержимого файлов;

more – постраничный просмотр содержимого файла.

mv – перемещение или переименование файла;

rm – удаление файла;

alias – создание псевдонима;

tr – преобразование символов;

exit – завершение текущегоshell -а;

tee – перехват результатов конвейера;

cut – выделение полей из строки;

grep – поиск по шаблону;

pr – вывод файла на стандартный вывод в заданном формате;

sort – сортировка;

head – вывод первых строк файла;

tail – вывод последних строк файла;

wc – подсчет количества символов, слов и строк;

read , echo - чтение и вывод значений переменных;

test - оценивание значения выражения;

expr , let - вычисление арифметических выражений;

8. Shell -программы

Shellпозволяет сохранять последовательность команд в файле и затем выполнять ее. Чтобы запускать файл с shell-программой на выполнение, нужно добавить к правам доступа право на исполнение:

$ chmod +x имя_файла_с_программой

Ветвление в shell-программах организуется с помощью операторов:

if-then-else

Операторы цикла:

УПРАЖНЕНИЯ

1. Какие из приведенных ниже команд приведут в выдаче приветственного сообщения на экран? Какие нет? Почему?

$ echo hello

$ Echo hello

$ echo HELLO, WORLD

$ banner hello

$ BANNER HELLO , WORLD

2. Выведите сообщение из нескольких строк с помощью команд echo иbanner.

3. Выведите дату в две строки: на первой день, месяц, год, на второйтекущее время, снабдив вывод комментарием.

4. Используя команду write , пошлите сообщение на консоль. Пошлите сообщения на несколько терминалов одновременно.

5. Используя команду mesg , определите, разрешены ли сообщения на Ваш терминал. Запретите сообщения. Какова будет реакция системы, если кто-нибудь попытается передать Вам сообщение?

6. Определите имя своего HOME -каталога.

7. Просмотрите поддерево каталогов, начиная с каталога /export/homeс помощью командcd, ls иpwd.

8.. Создайте в своем HOME -каталоге подкаталоги вида:

fruits flowers

apple pear grapes rose violet dandelion

dark green

9. Находясь в своем HOME -каталоге, создайте следующие подкаталоги, используя одну командную строку:

A/B/C/D

10. Находясь в своем HOME -каталоге, удалите все подкаталоги каталогаA.

11. Находясь в HOME -каталоге, создайте файлmacintosh в имеющемся каталогеapple и несколько файлов в каталогахdark иgreen . Войдите в каталогf lowers . Находясь в каталогеf lowers , скопируйте все подкаталогиf ruits вместе с находящимися в них файлами в специально созданный каталогbasket .

12. Находясь в каталоге f lowers , удалите каталогf ruits .

13. Прочитайте файл .profile с помощью командcat иmore.

14. Создайте в HOME -каталоге текстовый файлmyfile из нескольких строк с помощью командыcat. Создайте текстовый файлM y F ile, записав в него такие же строки. Сколько файлов у Вас получилось? Почему?

15. Просмотрите содержимое созданного в задаче 2.2 файла myfile . Скопируйте файлmyfile в файлmycopy. Просмотрите содержимое обоих файлов.

16. Переместите файл mycopy в каталогflowers.

17. Находясь в HOME -каталоге, создайте ссылкуm y link на файлmycopy , находящийся в каталогеflowers . Просмотрите файл-ссылку.

18. Добавьте строку к файлу my link . Какие из файловmy link , my copy , my file изменились? Почему?

19. С использованием какой команды можно определить число ссылок? Определите число ссылок для файлов my link , my copy , my file .

Удалите файл mycopy . Что произошло с файлом-ссылкой? Определите число ссылок для файловmy link , my file .

20. Создайте псевдоним dir , распечатывающий содержимое текущего каталога в расширенном формате.

21. Завершите сеанс работы и вновь зарегистрируйтесь. Работает ли псевдоним dir ? Что следует сделать, чтобы псевдоним «не терялся» между сеансами?

22. Создайте псевдоним point , распечатывающий список находящихся в рабочем каталоге файлов, имена которых начинаются с точки.

23. Используя команду touch , создайте файлы в новом каталоге с такими именами, чтобы одновременно:

Шаблону a * соответствовало 5 файлов;

Шаблону * a соответствовало 4 файла;

Шаблону ??.? соответствовало 3 файла;

Шаблону * aa * соответствовало 2 файла;

Шаблону??? соответствовал 1 файл.

24. Какую команду следует ввести, чтобы сделать следующее:

а) вывести имена всех файлов, начинающихся с точки;

б) вывести имена всех файлов, оканчивающихся на “.txt” ;

в) вывести имена всех файлов, содержащие слово “my” ;

25. Замените в одном заданном файле все строчные буквы на прописные, в другом – все прописные на строчные. Исключите из файла все повторяющиеся пробелы.

26. Создайте файл с именем * . Удалите только этот файл. Будьте осторожны при использовании символов генерации имен фпйлов!

27. Создайте файл, в имени которого есть символ «пробел». Как удалить такой файл?

28. С использованием команды cat удвойте содержимое файла, приписав исходное содержимое к концу этого же файла. Перейдите в каталогflowers . Добавьте в файлspisok список содержимого каталогаflowers. Просмотрите содержимое файла

29. Попытайтесь прочитать с помощью команды cat несуществующий файл. Какова реакция системы? Сделайте то же самое, перенаправив сообщения об ошибках в файлmyerror . Что Вы видите на экране? Просмотрите файлmyerror .

30. Создайте конвейер для получения списка только имен и прав доступа к файлам, которые в данный момент находятся в Вашем рабочем каталоге.

31. Измените построенный конвейер так, чтобы список сохранялся в файле spisok ВашегоHOME -каталога, а на экран выводилось только число файлов в списке.

32. Выведите на экран содержимое файла /etc/passwd , упорядоченное по полю с именем пользователя.

33. Создайте псевдоним logged on , который будет выводить на экран упорядоченный в алфавитном порядке список имен работающих в системе пользователей.

33. Выведите текущую дату на экран большими буквами с помощью команд date иbanner.

34. Присвойте переменной IAM Ваше имя регистрации. Запустите еще одинshell . Видите ли Вы эту переменную? Что нужно сделать, чтобы увидеть ее в порожденномshell ? Измените значение переменнойIAM в порожденномshell . Выйдите из порожденногоshell . Посмотрите значение этой переменной в исходномshell . Объясните результат.

35. Напишите shell -программуinfo , которая будет просить пользователя ввести имя, адрес, число, месяц и год рождения и выводить эту информацию в обратном вводу порядке

36. Напишите shell -программу, которая будет выводить на экран приглашение на ввод числа, сохранять введенное число в переменнойY , и печатать сообщение“Y is greater than 7”, если значениеY больше 7, и“Y is not greater than 7” в противном случае.

37. Напишите shell-программу, которая выводит на экран следующую статистику:

а) свое имя;

б) количество аргументов, с которыми она запущена;

в) печатает каждый свой аргумент и длину аргумента в символах;

38. Напишите shell -программу, которая определяет количество аргументов в командной строке и выдает сообщение об ошибке, если количество аргументов не равно трем, или сами аргументы, если их количество равно трем.

39. Напишите shell -программу, которая будет выдавать приглашение на ввод идентификатора пользователя, проверять идентификатор на соответствие используемым в системе и выводить полное имяHOME -каталога или, в случае недопустимого идентификатора, выдавать сообщение об ошибке.

40. Напишите shell-программу hello , обеспечивающую следующую реакцию на аргументы командной строки:

Аргумент “-d” - программа будет выполнять командуdate ;

Аргумент “-l” - программа выведет содержимое текущего каталога;

    при отсутствии аргументов или неправильных аргументах в командной строке программа будет выводить справку о своих опциях.

41. Напишите программу words , которая будет выдавать пользователю приглашение на ввод по одному слову до тех пор, пока он не введет словоend . Запомните все введенные слова. После ввода словаend выведите на экран все введенные слова.

42. Измените приглашение системы так, чтобы оно содержало полное маршрутное имя текущего рабочего каталога.

43. Напишите программу virus , которая создают свою выполняемую копию с другим именем, а затем сама себя удаляет.

44. Напишите программу virus 2 , которая ищет в текущем каталоге программы командного языка и добавляет в их текст команду вывода на экран словаInfected !”.

45. Напишите программу virus 3 , которая добавляет к найденным ею программам командного языка свой код для заражения других программ.

46. Напишите программу virus 4 , модифицировав ваш вирус так, чтобы при заражении заражающий код удалялся из заражающей программы.

47. Напишите программу antivirus , которая бы находила все зараженные вашим вирусомshell-программы.

48. Модифицируйте разработанную программу так, чтобы она не только находила зараженные программы в указанном ей каталоге, но и “вылечивала” бы их, сохраняя зараженную версию в новом файле, к имени которого добавлено окончание . vir , и снимая с такого файла атрибут выполнения.

49. Напишите программу virus 5 , которая бы:

а) заражала бы вирусом shell-программы в текущем каталоге и его подкаталогах, только если пользователь вводил командуls ;

б) вела бы себя как команда ls , ничем не выдавая на терминале своей работы.

50. Напишите программу virus6 на основе программvirus 2 -virus 5 , заражающий код которой нельзя было бы обнаружить разработанной Вами программойantivirus , а заражение происходило бы при любом значении переменнойPATH .

51. Напишите программу supervirus , запуск которой заражает Ваши файлы вирусом, разработанным в предыдущей задаче, а при каждом Вашем входе в систему делается попытка заразить файлы Ваших товарищей. Программаsupervirus стирает себя после первого запуска.

52. Напишите программу superantivirus , которая обнаруживает и полностью “излечивает” (если указана соответствующая опция) все файлы в указанном каталоге и его подкаталогах от всех разработанных вирусов.

Как только речь заходит об устройстве Linux и более или менее профессиональной работе с этой ОС, в примерах немедленно возникает и начинает доминировать командная строка. Из чего несложно сделать вывод, что это главный (и стандартный) интерфейс управления системой в Linux. Тот же проницательный читатель наверняка задастся вопросом - а кто же выполняет команды, введённые в командной строке? Ответ «система» окажется неправильным: в Linux нет отдельного объекта под именем «система». Система - она на то и система, чтобы состоять из многочисленных компонентов, взаимодействующих друг с другом.

Правильный ответ, как водится, оказывается более сложным. Операционная система нужна в частности для того, чтобы программы можно было писать, не думая о подробностях устройства компьютера и его деталей, начиная от процессора и жёсткого диска (скажем, на уровне «открыть файл», а не последовательности команд перемещения головки жёсткого диска). Операционная система управляет оборудованием сама, а программам предоставляет «язык» довольно высокого уровня абстракции, покрывающий все их необходимости, т. н. API . Но для команд пользователя такой язык не годится, поскольку он всё равно слишком низкоуровневый (для решения даже самой простой задачи пользователя необходимо выполнить несколько таких операций), да и воспользоваться им можно, только написав программу (чаще всего - на языке Си). Возникает необходимость выдумать для пользователя другой - более высокоуровневый и более удобный - язык управления системой. Все команды, которые можно ввести в командной строке, сформулированы именно на этом языке.

Из чего проницательному читателю несложно заключить, что обрабатывать эти команды, переводя их на язык операционной системы, должна тоже какая-нибудь специальная программа, и именно с ней ведёт диалог пользователь, работая с командной строкой. Так оно и есть: программа эта называется интерпретатор командной строки или командная оболочка («shell»). «Оболочкой» она названа как раз потому, что всё управление системой идёт как бы «изнутри» неё: пользователь общается с нею на удобном ему языке (с помощью текстовой командной строки), а она общается с другими частями системы на удобном им языке (вызывая запрограммированные функции).

Конечно, командных интерпретаторов в Linux несколько. Самый простой из них, появившийся в ранних версиях UNIX, назывался sh , или «Bourne Shell» - по имени автора, Стивена Борна (Stephen Bourne). Со временем его - везде, где только можно - заменили на более мощный, bash , "Bourne Again Shell" (2) bash превосходит sh во всём, особенно в возможностях редактирования командной строки. Помимо sh и bash в системе может быть установлен «The Z Shell», zsh , самый мощный на сегодняшний день командный интерпретатор (шутка ли, 22 тысячи строк документации), или tcsh , обновлённая и тоже очень мощная версия старой оболочки «C Shell», синтаксис команд которой похож на язык программирования Си.

Синтаксис командной строки

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

Результат выполнения очень многих команд также представляет собой текст, выдаваемый в качестве «ответа» пользователю. Хотя это и не обязательно - команда может выполнять свою работу совершенно молчаливо. Кроме того, если в процессе выполнения команды возникли какие-то особые обстоятельства (например, ошибка), оболочка включит в ответ пользователю диагностические сообщения .

Команда и параметры

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

$ cal
Июнь 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

$

Пример 1 . Команда cal


А если нужно посмотреть календарь на будущий месяц? Верно, не следует для этого изобретать отдельную команду , cal вполне справится с этой задачей, только её поведение нужно немного модифицировать:

$ cal 7 2008
Июль 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

Пример 2 . Команда cal с параметрами


Выходит, команда cal 7 2008 состоит как минимум из двух частей - собственно команды cal и «всего остального». Это остальное, что следует за командой, называют параметрами (или аргументами ), причём они вводятся для того, чтобы изменить поведение команды. В большинстве случаев при разборе командной строки первое слово считается именем команды, а остальные - её параметрами.

Слова

При разборе командной строки shell использует понятие разделитель (delimiter). Разделитель - это символ, разделяющий слова; таким образом командная строка - это последовательность слов (которые имеют значение) и разделителей (которые значения не имеют). Для shell разделителями являются символ пробела, символ табуляции и символ перевода строки. Количество разделителей между двумя соседними словами значения не имеет.

Для того, чтобы разделитель попал внутрь слова (и получившаяся строка с разделителем передалась как один параметр), всю нужную подстроку надо окружить одинарными или двойными кавычками: $ echo One Two Three
One Two Three
$ echo One "Two Three"
One Two Three
$ echo "One
>
> Ой. И что дальше?
> А, кавычки забыл!"

Пример 3 . Закавычивание в командной строке


Всё сказанное означает, что у команды столько параметров, сколько слов с точки зрения shell следует за ней в командной строке. Первое слово в тройке передаётся команде как первый параметр, второе - как второй и т. д. В первом случае команде echo было передано три параметра - “ One ”, “ Two ” и “ Three ”. Она их и вывела, разделяя пробелом. Во втором случае параметров было два : “ One ” и “ Two Three ”. В результате эти два параметра были также выведены через пробел. В третьем случае параметр был всего один - от открывающего апострофа “ "One ” до закрывающего “ ...забыл!" ”. Всё время ввода bash услужливо выдавал подсказку “ > ” - в знак того, что набор командной строки продолжается, но в режиме ввода содержимого кавычек.

Ключи

Для решения разных задач одни и те же действия необходимо выполнять слегка по-разному. Например, для синхронизации работ в разных точках земного шара лучше использовать единое для всех время (по Гринвичу), а для организации собственного рабочего дня - местное время (с учётом сдвига по часовому поясу и разницы зимнего и летнего времени). И то, и другое время показывает команда date , только для работы по Гринвичу ей нужен дополнительный параметр “ -u ” (он же “ --universal ”).


Пнд Июн 16 18:03:44 MSD 2008
$ date -u
Пнд Июн 16 14:03:46 UTC 2008

Пример 4 . Команда date с ключом


Такого рода параметры называются модификаторами выполнения или ключами (options) . Ключ принадлежит данной конкретной команде и сам по себе смысла не имеет, чем отличается от прочих параметров (например, имён файлов, чисел), которые имеют собственный смысл, не зависящий ни от какой команды. Каждая команда может распознавать некоторый набор ключей и соответственно изменить своё поведение. В результате «один и тот же» ключ, например, “ -s ” может значить для разных команд совершенно разные вещи.

Для формата ключей нет жёсткого стандарта, однако существуют договорённости, нарушать которые в наше время уже неприлично. Во-первых, если параметр начинается на “ - ”, это - однобуквенный ключ . За “ - ”, как правило, следует один символ, чаще всего - буква, обозначающая действие или свойство, которое этот ключ придаёт команде. Так проще отличать ключи от других параметров - и пользователю при наборе командной строки, и программисту, автору команды.

Во-вторых, желательно, чтобы имя ключа было значащим - как правило, это первая буква названия действия или свойства, обозначаемого ключом. Например, ключ “ -a ” в man и who происходит от слова «A ll» (всё), и изменяет работу этих команд так, что они начинают показывать информацию, о которой обычно умалчивают. А в командах cal и who смысл ключа “ -m ” - разный:

$ who -m
methody tty1 Sep 20 13:56 (localhost)
$ cal -m
Июнь 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

Пример 5 . Использование ключа “ -m ” в разных командах


Для who ключ “ -m ” означает «M e», то есть «Я», и в результате who работает похоже на whoami . А для cal ключ “ -m ” - это команда выдать календарь, считая первым днём понедельник M onday»), как это принято в России.

Свойство ключа быть, с одной стороны, предельно коротким, а с другой стороны - информативным, называется аббревиативностью . Не только ключи, но и имена наиболее распространённых команд Linux обладают этим свойством.

В-третьих, иногда ключ изменяет поведение команды таким образом, что меняется и толкование параметра, следующего в командной строке за этим ключом. Выглядит это так, будто ключ сам получает параметр, поэтому ключи такого вида называются параметрическими . Как правило, их параметры - имена файлов различного применения, числовые характеристики и прочие значения , которые нужно передать команде. -s 00:00
date: невозможно установить дату: Operation not permitted
Пнд Июн 16 00:00:00 MSK 2008
$ date
Пнд Июн 16 18:30:53 MSK 2008

Пример 6 . Использование date -s


Ключ “ -s ” команды date позволяет установить системное время в то значение, которое указывается в качестве параметра этого ключа. Однако в данном примере эта операция не удалась, о чём свидетельствует выведенное сообщение об ошибке . Для изменения системных часов требуются привилегии системного администратора, а в нашем примере эта команда выполнялась от имени обычного пользователя. Тем не менее, date всё равно отобразил время, которое нужно было установить, хотя системные часы и остались не изменёнными.

Аббревиативность ключей трудно соблюсти, когда их у команды слишком много. Некоторые буквы латинского алфавита (например, “ s ” или “ o ”) используются очень часто, и могли бы служить сокращением сразу нескольких команд, а некоторые (например, “ z ”) - редко, под них и название-то осмысленное трудно придумать. На такой случай существует другой, полнословный формат: ключ начинается на два знака “ - ”, за которыми следует полное имя обозначаемой им сущности. Таков, например, ключ “ --help ” (аналог “ -h ”): $ head --help
Использование: head [КЛЮЧ]... [ФАЙЛ]...
Печатает первые 10 строк каждого ФАЙЛА на стандартный вывод.
Если задано несколько ФАЙЛОВ, сначала печатает заголовок с именем файла.
Если ФАЙЛ не задан или задан как -, читает стандартный ввод.

Аргументы, обязательные для длинных ключей, обязательны и для коротких.
-c, --bytes=[-]N напечатать первые N байт каждого файла;
последних байт каждого файла
-n, --lines=[-]N напечатать первые N строк каждого файла, а не 10;
если перед N стоит `-", напечатать все, кроме N
последних строк каждого файла
-q, --quiet, --silent не печатать заголовки с именами файлов
-v, --verbose всегда печатать заголовки с именами файлов
--help показать эту справку и выйти
--version показать информацию о версии и выйти

N может иметь суффикс-множитель: b 512, k 1024, m 1024*1024.

Об ошибках сообщайте по адресу .

Пример 7 . Ключ–help


Видно, что некоторые ключи head имеют и однобуквенный, и полнословный формат, а некоторые - только полнословный. Так обычно и бывает: часто используемые ключи имеют аббревиатуру, а редкие - нет. Значения параметрических полнословных ключей принято передавать не следующим параметром командной строки, а с помощью конструкции “ =значение ” непосредственно после ключа.

В-четвёртых, есть некоторые менее жёсткие, но популярные договорённости о значении ключей. Ключ “ -h ” («H elp») обычно (но, увы, не всегда) заставляет команды выдать краткую справку . Наконец, бывает необходимо передать команде параметр, а не ключ , начинающийся с “ - ”. Для этого нужно использовать ключ “ -- ”: $ head -1 -filename-with-
head: invalid option -- f
Попробуйте `head --help" для получения более подробного описания.
$ head -1 -- -filename-with-
Первая строка файла -filename-with-

Пример 8 . Параметр–не ключ, начинающийся на “ - ”


Ключ “ -- ” (первый “ - ” - признак ключа, второй - сам ключ) обычно запрещает команде интерпретировать все последующие параметры командной строки как ключи, независимо от того, начинаются ли они на “ - ” или нет. Только после “ -- ” head согласилась с тем, что -filename-with- - это имя файла.

Синопсис

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

Cal [-smjy13] [ year]

Пример 9 . Синопсис для команды cal


В синопсисе даётся формализованное описание способов использования объекта (с данном случае - того, как и с какими параметрами запускать команду cal). Параметры перечисляются в том же порядке, в котором их нужно вводить в командной строке, необязательные параметры, как правило, даются в квадратных скобках, обязательные - вообще без скобок, а ключи для компактности собираются в один параметр, в котором каждая буква - это отдельный ключ. Приведённый пример читается так: у команды cal нет обязательных параметров, есть (необязательные) ключи (-s , -m и т. д.), и необязательный параметр year , перед которым может присутствовать необязательный же month (но не может быть указан month без year).

Откуда берутся команды

Дочитав предыдущий раздел, проницательный читатель должен был подумать примерно так: ага, ну с командами и параметрами (т. е. с грамматикой командной строки) мы немного разобрались, вооружите же нас теперь списком всех команд Linux (иначе говоря, словарём), и мы примемся за работу. Почему же нигде не напечатан такой список? Точнее, списков команд много разных и все они очевидно неполные и не во всём сходятся. Ответ на этот вопрос состоит из двух частей.

Часть 1: команды и утилиты

Shell, командный интерпретатор, является «оболочкой» не только для пользователя, но и для команд: сам он почти никакие команды не исполняет, передаёт системе. Его задача сводится к тому, чтобы разобрать командную строку, выделить из неё команду и параметры, а затем запустить утилиту - программу, имя которой совпадает с именем команды.

Если смотреть «изнутри» командного интерпретатора, то работа с командной строкой происходит примерно так: пользователь вводит строку (команду), shell считывает её, иногда - преобразует по определённым правилам, получившуюся строку разбивает на команду и параметры, а затем запускает утилиту, передавая ей эти параметры. Утилита, в свою очередь, анализирует параметры, выделяет среди них ключи, и делает что попросили, попутно выводя данные для пользователя, после чего завершается. По завершении утилиты возобновляется работа «отступившего на задний план» командного интерпретатора, он снова считывает командную строку, разбирает её, вызывает команду... Так продолжается до тех пор, пока пользователь не скомандует оболочке завершиться самой (с помощью команды logout или управляющего символа Ctrl+D ).

Однако часть команд (меньшую) оболочка всё же выполняет самостоятельно, не вызывая никаких утилит. Некоторые - самые нужные - команды встроены в bash , даже несмотря на то, что они имеются в виде утилит (например, echo). Работает встроенная команда так же, но так как времени на её выполнение уходит существенно меньше, командный интерпретатор выберет именно её, если будет такая возможность. В bash тип команды можно определить с помощью команды type . Собственные команды bash называются builtin (встроенная команда), а для утилит выводится путь , содержащий название каталога, в котором лежит файл с соответствующей программой, и имя этой программы. Ключ “ -a ” («a ll», конечно), заставляет type вывести все возможные варианты интерпретации команды, а ключ “ -t ” - вывести тип команды вместо пути.

$ type date
info is /bin/date
$ type echo
echo is a shell builtin
$ type -a echo
echo is a shell builtin
echo is /bin/echo
$ type -a -t echo
builtin
file

Пример 10 . Определение типа команды


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

Часть 2: всему своё руководство

Каждый объект системы: все утилиты , все демоны Linux, все функции ядра и библиотек , структура большинства конфигурационных файлов , наконец, многие умозрительные, но важные понятия - должны обязательно сопровождаться документацией, описывающей их назначение и способы использования. Поэтому от пользователя системы не требуется заучивать все возможные варианты взаимодействия с ней. Достаточно понимать основные принципы её устройства и уметь находить справочную информацию. Эйнштейн говорил на этот счёт так: «Зачем запоминать то, что всегда можно посмотреть в справочнике?».

Больше всего различной полезной информации содержится в страницах руководства (manpages ). Каждая страница руководства (для краткости - просто «руководство») посвящена какому-нибудь одному объекту системы. Для того, чтобы посмотреть страницу руководства, нужно дать команду man объект : $ man cal
CAL(1) BSD General Commands Manual CAL(1)

NAME
cal - displays a calendar

SYNOPSIS
cal [-smjy13] [ year]

DESCRIPTION
Cal displays a simple calendar. If arguments are not specified,
the current month is displayed. The options are as follows:
. . .

Пример 11 . Просмотр страницы руководства


«Страница руководства» занимает, как правило, больше одной страницы экрана . Для того, чтобы читать было удобнее, man запускает программу постраничного просмотра текстов - less . Управлять программой less просто: страницы перелистываются пробелом, а когда читать надоест, надо нажать “ q ” (Quit). Перелистывать страницы можно и клавишами Page Up / Page Down , для сдвига на одну строку вперёд можно применять enter или стрелку вниз, а на одну строку назад - стрелку вверх. Переход на начало и конец текста выполняется по командам “ g ” и “ G ” соответственно (Go). Полный список того, что можно делать с текстом в less , выводится по команде “ H ” (Help).

Страница руководства состоит из полей - стандартных разделов, с разных сторон описывающих объект. При первом изучении руководства стоит начать с полей NAME (краткое описание объекта) и DESCRIPTION (развёрнутое описание объекта, достаточное для того, чтобы им воспользоваться). Одно из самых важных полей руководства находится в конце текста. Если в процессе чтения NAME или DESCRIPTION пользователь понимает, что не нашёл в руководстве того, что искал, он может захотеть посмотреть, а есть ли другие руководства или иные источники информации по той же теме . Список таких источников содержится в поле SEE ALSO:

$ man man
. . .
SEE ALSO
apropos(1), whatis(1), less(1), groff(1), man.conf(5).
. . .

Пример 12 . Поле SEE ALSO руководства


В поле SEE ALSO обнаружились ссылки на руководства по less , groff (программе форматирования страницы руководства), структуре конфигурационного файла для man , а также по двум сопутствующим командам whatis и apropos , которые помогают отыскать нужное руководство. Обе они работают с базой данных, состоящей из полей NAME всех страниц руководства в системе. Различие между ними - в том, что whatis ищет только среди имён объектов (в левых частях полей NAME), а apropos - по всей базе. В результате у whatis получается список кратких описаний объектов с именами , включающими в себя искомое слово, а у apropos - список, в котором это слово упоминается .

В системе может встретиться несколько объектов разного типа, но с одинаковым названием. Часто совпадают, например, имена системных вызовов (функций ядра ) и утилит, которые позволяют пользоваться этими функциями из командной строки. При ссылке на руководство по объекту системы принято непосредственно после имени объекта ставить в круглых скобках номер раздела, в котором содержится руководство по этому объекту: man(1) , less(1) , passwd(5) . По такому формату легко опознать, что имеется в виду руководство.

В системе руководств Linux девять разделов, каждый из которых содержит страницы руководства к объектам определённого типа. Все разделы содержат по одному руководству с именем «intro», в котором в общем виде и на примерах рассказано, что за объекты имеют отношение к данному разделу. Список разделов с названиями можно получить командой whatis intro .

По умолчанию man просматривает все разделы и показывает первое найденное руководство с заданным именем. Чтобы посмотреть руководство по объекту из определённого раздела, необходимо в качестве первого параметра команды man указать номер раздела, например, man 8 passwd .

Другой источник информации о Linux и составляющих его программах - справочная подсистема info . Страница руководства, несмотря на обилие ссылок различного типа, остаётся «линейным» текстом, структурированным только логически. Документ info - это настоящий гипертекст, в котором множество небольших страниц объединены в дерево. В каждом разделе документа info всегда есть оглавление, из которого можно перейти сразу к нужному подразделу, откуда всегда можно вернуться обратно. Кроме того, info-документ можно читать и как непрерывный текст, поэтому в каждом подразделе есть ссылки на предыдущий и последующий подразделы. Можно догадаться, что подробное руководство по тому, как перемещаться между страницами в info можно получить по команде info info . Команда info , введённая без параметров, предлагает пользователю список всех документов info , установленных в системе.

Если некоторый объект системы не имеет документации ни в формате man , ни в формате info , это нехорошо. В этом случае можно надеяться, что при нём есть сопроводительная документация , не имеющая, увы, ни стандартного формата, ни тем более - ссылок на руководства по другим объектам системы. Такая документация (равно как и примеры использования объекта), обычно помещается в каталог /usr/share/doc/имя_объекта .

Документация в подавляющем большинстве случаев пишется на простом английском языке. Если английский - не родной язык для автора документации, она будет только проще. Традиция писать по-английски идёт от немалого вклада США в развитие компьютерной науки вообще и Linux в частности. Кроме того, английский становится языком международного общения во всех областях, не только в компьютерной. Необходимость писать на языке, который будет более или менее понятен большинству пользователей, объясняется постоянным развитием Linux. Дело не в том, что страницу руководства нельзя перевести, а в том, что её придётся переводить всякий раз , когда изменится описываемый ею объект! Например, выход новой версии программного продукта сопровождается изменением его возможностей и особенностей работы, а следовательно, и новой версией документации. Тогда перевод этой документации превращается в «moving target», сизифов труд.

Тем не менее, некоторые наиболее актуальные руководства всё-таки существуют в переводе на русский язык. Наиболее свежие версии таких переводов на русский собраны в пакете man-pages-ru - достаточно установить этот пакет, и те руководства, для которых есть перевод, man будет по умолчанию отображать на русском языке.

Переменные окружения

Помимо параметров, передаваемых в командной строке, в Linux есть ещё один способ модифицировать поведение программы - для этого используются переменные окружения . Чтобы объяснить принцип работы переменных окружения, потребуется небольшой экскурс в механизм взаимодействия процессов в Linux.

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

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

Создание одного процесса другим называется порождением процесса и происходит в два этапа: сначала создаётся точная копия исходного, родительского процесса (системный вызов fork()), а затем копия процесса подменяется новым, дочерним (системный вызов exec()). Для нас сейчас важно, что при этой подмене сохраняются все свойства исходного процесса, и, в частности, окружение.

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

Одна и та же утилита может быть использована одним и тем же способом, но в изменённом окружении - и выдавать различные результаты. Пользователь может явно изменить окружение для запускаемого процесса, присвоив некоторое значение переменной окружения в командной строке перед именем команды. Командный интерпретатор, увидев “ = ” внутри первого слова командной строки, приходит к выводу, что это - операция присваивания, а не имя команды, и запоминает, как надо изменить окружение команды, которая последует после.

$ date
Пнд Июн 16 18:28:30 MSK 2008
$ LC_TIME=C date
Mon Jun 16 18:28:51 MSK 2008

Пример 13 . Утилита date пользуется переменной окружения LC_TIME


Переменная окружения LC_TIME предписывает использовать определённый язык при выводе даты и времени а значение “ C ” соответствует «стандартному системному» языку (чаще всего - английскому).

Переменные, которые командный интерпретатор bash определяет после запуска, не принадлежат окружению, и, стало быть, не наследуются дочерними процессами. Чтобы переменная bash попала в окружение, её надо проэкспортировать командой export: $ LC_TIME=C
$ date
Пнд Июн 16 18:29:17 MSK 2008
$ export LC_TIME=C
$ date
Mon Jun 16 18:29:38 MSK 2008

Пример 14 . Экспорт переменных shell в окружение


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

К значению любой переменной в bash можно обратиться по имени: вместо конструкции $имя_переменной оболочка подставит значение этой переменной. Например, для того, чтобы просмотреть значение некоторой переменной, пользователь может ввести команду echo $имя_переменной .

Echo $PATH
/home/methody/bin:/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:/usr/games

Пример 15 . Вывод значения переменной


Весьма примечательна переменная окружения PATH . В ней содержится список каталогов, элементы которого разделяются двоеточиями. Если команда в командной строке - не собственная команда shell (вроде cd) и не предствалена в виде пути к запускаемому файлу (как /bin/ls или./script), то shell будет искать эту команду среди имён запускаемых файлов во всех каталогах PATH , и только в них. По этой причине исполняемые файлы невозможно запускать просто по имени, если они лежат в текущем каталоге, и текущий каталог не входит в PATH . В таких случаях можно воспользоваться кратчайшим из возможных путей, “ ./ ” (например, вызывая сценарий./script).

Переменных окружения, влияющих на работу разных утилит, довольно много. Например, переменные семейства LC_ (полный их список выдаётся командой locale), определяющие язык, на котором выводятся диагностические сообщения, стандарты на формат даты, денежных единиц, чисел, способы преобразования строк и т. п. Если какая-то утилита требует редактирования файла, этот файл передаётся программе, путь к которой хранится в переменной EDITOR (обычно это /usr/bin/vi), а если потребуется открыть html-файл, то многие утилиты вызовут для этого программу, указанную в переменной BROWSER . Наконец, некоторые переменные вроде UID , USER или PWD просто содержат полезную информацию, которую можно было бы добыть и другими способами.

Нестандартный набор параметров: who am i делает то же, что и who -m .



© 2024 beasthackerz.ru - Браузеры. Аудио. Жесткий диск. Программы. Локальная сеть. Windows