Banner - вывод сообщения на экран заглавными буквами (например для идентификации следующих за ним сообщений).




$banner 'hello ira'

HELLO IRA

$

 

Простейший пример. Здесь оператор echo выполняется в командном режиме.

$shfil p1 pp2 petr

$echo $3

petr

$

 

 

Значения параметрам, передаваемым процедуре, можно присваивать и в процессе работы процедуры с помощью оператора

set - присвоить значения позиционным параметрам;

 

Пример.

$set a1 ab2. abc

$echo $1 $2

a1 ab2 - в этом примере параметры указываются в явном виде.

$

Количество позиционных параметров может быть увеличено до

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

shift - сдвинуть позиционные параметры влево на одну позицию

 

После выполнения shift прежнее значение параметра $1 теря-

ется, значение $1 приобретает значение $2, значение $2 - значение $3 и т.д..

Продолжение предыдущего примера:

$shift

$echo $1 $2

ab2 abc

$

В UNIX при написании операторов важное значение отводится

Кавычкам (апострофам):

'...' - для блокирования специальных символов, которые

могут быть интерпретированы как управляющие;

"..." - блокирование наиболее полного набора управляющих символов или указания того, что здесь будет обрабатываться не сам аргумент, а его значение;

`...` - (обратные кавычки или знак ударения) для указания

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

 

Пример 1.

$ date

Apr 3 14:27:07 2005

$ set `date`

$ echo $3

14:30:25

$

 

Пример 2.

$echo `ls`

fil.1

fil.2

...

$echo '`ls`'

# одинарные кавычки блокируют действие обратных кавычек

# т.е. они распечатываются как обычные символы

`ls`

$

 

Пример 3.

$ls -al|grep “Mar 30”

- выводится информация о всех файлах текущего каталога, модифицированных 30 марта всех годов;

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

$ls -al|grep Mar 30

- здесь Mar –шаблон, а 30 – имя файла.

 

 

Для ввода строки текста со стандартного устройства ввода используется оператор:

read имя1 [имя2 имя3.] - чтение строки слов со стандартного ввода

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

Пример (предполагает наличие программы –русификатора):

#Текст процедуры:

echo "Введите значения текущих: гг мм ччвв"

read 1v 2v 3v

echo "год 1v"

echo "месяц 2v"

echo "сегодня 3v"

# здесь кавычки используются для блокирования пробелов

#Результат выполнения процедуры:

Введите значения текущих: гг мм ччвв

2005 Maрт 21 9:30 <Enter>

год 2005

месяц Maрт

сегодня 21 9:30

 

 

Тема 21. УПРАВЛЕНИЕ ЛОКАЛЬНЫМИ ПЕРЕМЕННЫМИ

 

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

"=" - присвоить (установить) значение переменной.

При этом если переменная существовала, то новое значение замещает старое. Если переменная не существовала, то она строится автоматически shell. Переменные хранятся в области ОП - области локальных данных.

 

$count=3

$color=red belt

$fildir=lev/d1/d12

$

Еще пример:

# текст процедуры

b=”1 + 2”

echo c=$b

#в результате выполнения процедуры выводится текст,

# включающий текст переменной b

c=1+2

 

 

Тема 22. ПОДСТАНОВКА ЗНАЧЕНИЙ ПЕРЕМЕННЫХ

 

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

$имя_переменной -. на место этой конструкции будет

подставлено значение переменной.

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

Аналогичного результата можно достич и следующим образом:

“имя_переменной”

Значения переменных могут представлять собой:

· абсолютные числовые или символьные значения,

· команды,

· аргументы команд или целиком командные строки.

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

 

Примеры подстановки длинных маршрутных имен:

$echo $HOME

/home/lev

$filname=$HOME/f1

$more $filname

<текст файла f1 из каталога lev>

$

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

 

Если в строке несколько присваиваний, то последователь-

ность их выполнения - справа налево.

Пример 1.

 

$ z=$y y=123

$ echo $z $y

123 123

$ y=abc z=$y

$ echo “z”

 

$ echo “y”

abc

$

 

Пример 2.

$ var=/user/lab/ivanov

$ cd $var

$ pwd

/udd/lab/ivanov

$

Таким образом, задано и установлено имя текущего каталога.

 

Пример 3.

$ namdir='ls'

$ $namdir

fil1

fil2

fil3

...

$

В данном примере переменной namdir присвоено значение, которое затем используется в качестве командной строки запускаемой команды. Это команда ls.

Второй вид подстановки – подстановка результатов работы команды вместо самой коиъманды.

 

Пример 4.

$ filnam=`ls`

$ echo $filnam

fil1

fil2

fil3

...

$

В данном случае команда ls непосредственно выполняется уже

в первой строке, и переменной filnam присваивается результат ее работы.

 

Пример 5.

$ A=1 B=2

$ dat="$A + $B"

$ echo $dat

1 + 2

$

 

 

С переменными можно выполнять арифметические действия как

и с обычными числами c использованием специального оператора:

expr - вычисление выражений.

 

Для арифметических операций, выполнимых командой expr, ис-

пользуются операторы:

+ сложение;

- вычитание;

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

/ деление нацело;

% остаток от деления.

 

Для логических операций арифметического сравнения чисел

командой expr используются следующие обозначения:

= равно;!= не равно;

\< меньше; \<= меньше или равно;

\> больше; \>= больше или равно.

Символы * < > необходимо экранировать, как показано, чтобы

отменить их специальный смысл - шаблон имен файлов (для *) и

перенаправление потоков ввода и вывода (для < и >). Результатом

операции арифметического сравнения чисел командой expr является

вывод ею кода возврата числа 0 (true) или 1 (false).

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

 

Пример 6.

# Текст процедуры:

a=2

a=`expr $a + 7`

b=`expr $a / 3`

c=`expr $a - 1 + $b`

d=`expr $c % 5`

e=`expr $d - $b`

echo $a $b $c $d $e

 

#Результат работы процедуры:

9 3 11 1 -2

 

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

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

Операция обработки строк символов задается кодом операции

": " и шаблонами. В частности:

'.*' - шаблон для подсчета числа символов в строке,

'...\(.*\)....' - шаблон для выделения подстроки удалением символов строки, соответствующих точкам в шаблоне.

 

Пример 7.

$ m=aaaaaa

$ expr $m: '.*'

$

 

Пример 8.

$ n=abcdefgh

$ expr $n: ✧...\(.*\)..'

def

$

 

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

 

 

Третий вид подстановки - применяется для подстановки команд или целых shell-процедур. Используется для замены кода команды или текста процедуры на результат их выполнения в той же командной строке:

$(командная_строка) - подстановка осуществляется также перед запуском на исполнение командной строки.

Эта форма подстановки является альтернативой рассмотренной выше конструкциии, использующей заключение команды между знаками тупого ударения:

`командная_строка`, когда также выполняется процедура подстановки.

В данном случае в качестве подставляемой команды может быть использована также любая имеющая смысл sh-процедура. Shell просматривает командную строку и выполняет все команды между открывающей и закрывающей скобками.

Рассмотрим примеры присвоения значений и подстановки значений локальных переменных.

 

Пример 9.

$ A='string n'

$ count=$(expr $A: '.*')

$ echo $count

$

#Продолжение примера:

$ B=$(expr $A: '..\(.*\))

$ echo $B

ring

$

Рассмотрим пример на разработку простейшей линейной процедуры обработки переменных средствами языка shell.

ЗАДАНИЕ: Создать файл, содержащий процедуру сложения двух чисел. Числа передаются в виде параметров при обращении к процедуре. Выполнить процедуру.

 

$ cat>comf

SUM=$(expr $1 + $2)

echo "$1 + $2 = $SUM"

<Ctrl*D>

$ sh comf 3 5

3 + 5 = 8

$

 

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

$ set

$

Удаление переменных:

$unset перем1 [перем2........]

$

 

 

Тема 23. ЭКСПОРТИРОВАНИЕ ЛОКАЛЬНЫХ ПЕРЕМЕННЫХ В СРЕДУ shell

 

При выполнении процедуры ей можно передавать как позиционные параметры (см. выше) так и ключевые - локальные переменные порожденного процесса. Локальные переменные помещаются в область локальных переменных, связанную с конкретным текущим процессом, породившим переменную. Они доступны только этому процессу и недоступны порожденным процессам-потомкам (например – sh-процедурам). Переменные другим процессам можно передавать неявно через среду. Для этого локальная переменная должна быть экспортирована (включена) в среду, в которой исполняется процедура, использующая эту переменную. Среда пользователя, т.е. глобальные переменные, доступна всем процессам.

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

Три формата команды экспортирования:

 

$export список имен локальных переменных

$export имя_лок_переменной=значение

$export (без параметров) - выводит перечень всех экспортированных локальных и переменных среды (аналог команды env).

 

Рассмотрим некоторый фрагмент протокола работы с системой.

$color = red переменная определена, но не экспортирована

$export count = 1 переменная определена и экспортирована, т.е.

потенциально доступна всем порождаемым

процессам

$export

PATH = …..

HOME = …..

color = red

count = 1

$cat proc1 создание порожденного процесса процедуры

echo $color

echo $count

exit завершение процесса

<ctrl.D>

$proc1 выполнение процедуры

1 на экран выводится значение только одной,

экспортированной переменной; вторая переменная –

- не определена

$cat proc2 еще одна процедура

color = black

count = 2

echo $color

echo $count

exit

$proc2

black

2 выводятся значения обеих переменных, т.к. они

определены в самой поцедуре

$echo $color

red

$echo $count

$

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

 

 

Еще пример.

$export color=black

$kch

$echo $color

black

$color = red

$echo $color

red

$exit

$echo $color

black

$

Здесь порожденным процессом является вторичная оболочка Korn schell. Среда родительского процесса не изменена, т.е. сохранилось значение экспортированной в нее переменной. Порожденные процессы не могут изменить среду родительских процессов.

 

 

Тема 24. ПРОВЕРКА УСЛОВИЙ

И ВЕТВЛЕНИЕ ВЫЧИСЛИТЕЛЬНЫХ ПРОЦЕССОВ

 

Все команды UNIX вырабатывают код завершения (возврата), обычно для того, чтобы в дальнейшем можно было выполнить диагностику посредством проверки значения кода завершения и определить: нормально завершилось выполнение команды (=0 или true) или не нормально (# 0 или false). Например, если (=1), то ошибка синтаксическая.

Код завершения после выполнения каждой команды помещается автоматьически в некоторую специальную системную переменную и ее значение можно вывести на экран:

echo $?

 

Пример:

$true

$echo $?

$ls

$echo $?

$false

$echo $?

$cp

<сообщение о некорректности заданной команды – нет параметров>

$echo $?

$echo $?

$

 

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

test <проверяемое отношение/условие>

Вместо мнемоники команды может использоваться конструкция c квадратными скобками:

[проверяемое отношение/условие] синоним команды test.

 

Аргументами этой команды могут быть имена файлов, числовые

или нечисловые строки (цепочки символов). Командой вырабатывается код завершения (код возврата), соответствующий закодированному в команде test условию. Код завершения проверяется следующей командой. Если закодированное параметрами условие выполняется, то вырабатывается логический результат (значение некоторой системной переменной) - true, если нет - false.

Код возврата может обрабатываться как следующей за test командой, так и специальной конструкцией языка: if-then-else-fi.

 

1. Проверка файлов:

 

Test -к имя_файла

 

Ключи:

-r файл существует и доступен для чтения;

-w файл существует и доступен для записи;

-x файл существует и доступен для исполнения;

-f файл существует и имеет тип "-", т.е. обычный файл;

-s файл существует, имеет тип "-" и не пуст;

-d файл существует и имеет тип "d", т.е. файл - каталог.

……………………..

2. Сравнение числовых значений:

 

Test число1 –к число2

 

Числа могут быть как просто числовыми строками, так и переменными, которым эти строки присвоены в качестве значений.

 

Ключи для анализа числовых значений:

-eq равно; -n e не равно;

-lt меньше; -le меньше или равно;

-gt больше; -ge больше или равно.

 

 

Пример:

$x=5

$[$x -lt 7]

$echo $?

$[$x -gt 7]

$echo $?

$

 

3. Сравнение строк:

test [-n] 'строка' - строка не пуста (n – число проверяемых строк)

test -z 'строка' - строка пуста

test 'строка1' = 'строка2' - строки равны

test 'строка1'!= 'строка2' - строки не равны

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

 

Пример.

$x = abc

$["$x" = "abc"]

$echo $?

$["$x"!= "abc"]

$echo $?

$

ЗАМЕЧАНИЕ: выражение вида "$переменная" лучше заключать в двойные кавычки, что предотвращает в некоторых ситуациях возможную неподходящую замену переменных shell-ом.

Особенности сравнения чисел и строк. Shell трактует все аргументы как числа в случае, если осуществляется сравнение чисел, и все аргументы как строки, если осуществляется сравнение строк. Пример:

$X = 03

$Y =3

$["$X -eq "$Y"] - сравниваются значения чисел

$echo $?

$["$X = "$Y"] - числа сравниваются как строки символов

$echo $?

$

Ветвление вычислительного процесса в shell-процедурах осуществляется семантической конструкцией:

 

If список_команд1

Then список_команд2

[else список_команд3

fi

 

Список_команд - это или одна команда или несколько команд, или фрагмент shell-процедуры. Если команды записаны на одной строке, то они разделяются точкой с запятой.

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

 

: (двоеточие) -пустой оператор.

 

Список_команд1 передает оператору if код завершения последней выполненной в нем команды. Если он равен 0, то выполняется список_команд2.Таким образом, код возврата 0 эквивалентен логическому значению "истина". В противном случае он эквивалентен логическому значению "ложь" и выполняется либо список_команд3 после конструкции else, либо - завершение конструкции if словом fi.

 

В качестве списка_команд1 могут использоваться списки любых

команд. Однако, чаще других используется команда test.

В операторе if так же допускается две формы записи этой команды:

 

if test аргументы

if [ аргументы ]

 

Каждый оператор if произвольного уровня вложенности обязательно должен завершаться словом fi.

 

 

ЗАДАНИЕ: cоздать и выполнить файл с процедурой, сравнивающей передаваемый ей параметр с некоторым набором символов (паролем).

$ cat>com

if test 'param' = "$1" - сравниваются строки символов

then echo Y

else echo N

fi

<Ctrl*D>

$ chmod u+x com

$ com param

Y

$ com parm

N

$

 

ЗАДАНИЕ. Организовать ветвление вычислительного процесса в процедуре в зависимости от значения переменной Х (<10, >10, = 10).

if

[$X -lt 10]

then

echo X is less 10

else

if

[$X -gt 10]

then

echo X is greatr 10

else

echo X is equal to 10

fi

fi

Для улучшения восприятия программ и облегчения отладки целесообразно придерживаться структурированного стиля написания программы. Каждому if должен соответствовать свой fi.

 

 

Тема 25. ПОСТРОЕНИЕ ЦИКЛОВ

 

Циклы обеспечивают многократное выполнение отдельных

участков процедуры до достижения заданных условий.

 

Цикл типа while (пока true):

 

While список_команд1

Do список_команд2

Done

 

Список_команд1 возвращает код возврата последней выполненной команды. Если условие истинно, выполняется список_- команд2, затем снова список_команд1 с целью проверки условия, а если ложно, выполнение цикла завершается. Таким образом, циклический список_команд2 выполняется до тех пор, пока условие истинно.

 

Пример 1.

Проверка наличия параметров при обращении к данной процедуре. Вывод на экран сообщений о наличии параметров и тексты параметров.

 

Текст процедуры, которой присвоено имя Р1:

if $1 –eq 0

then echo “No param”

else echo “Param:’; while test ‘$1’

do

echo “$1”

shift

done

fi

Результат работы процедуры:

$P1

No param

$P1 abc df egh

Param:

abc

df

egh

$

 

Пример 2.

Ввод строки из нескольких слов. Подсчет и вывод числа символов в каждом слове.

Текст процедуры, которой присвоено имя P2:

echo “Input string:”

read A

set $A

while [ “$1” ]

do

echo “$1 = `expr ”$1”: ‘.*’`”

shift

done

 

 

Результат работы процедуры:

$P2

Input string:

df ghghhhh aqw

df = 2

ghghhhh = 7

aqw = 3

$

 

Пример 3. Вывести на экран слово строки (поле), номер которого (переменная N) указан в параметре при обращении к процедуре, которой присвоено имя P3. Процедура запрашивает ввод строки с клавиатуры. Номер слова вводится как аргумент процедуры.

 

Текст процедуры P3:

i=1 - счетчик номеров слов в строке, формируется при каждом

выполнении цикла

N=$1 -значение первого параметра

echo "Введи строку: "

read a

set $a

while test $i -lt $N

do

i=`expr $i + 1` - формирование номера следующего слова

shift

done

echo "$N поле строки: \"$1\""

 

Пример работы процедуры P3:

$P3 2 <NewLine> - N=2

Введи строку: aa bb cc dd <NewLine>

2 поле строки: "bb"

$

 

 

Цикл типа until (пока false):

Until список_команд1

Do список_команд2

Done

Логическое условие, определяемое по коду возврата

списка_команд1, инвертируется, т.е. цикл выполняется до тех

пор, пока условие ложно.

 

Пример процендуры с именем P4, выполняющей заданное число циклов.

$cat>P4

X = 1 - cчетчик числа циклов

until test $X -gt 10 - задано число циклов = 10

do

echo X is $X

X = `expr $X + 1`

done

<Ctrl*D>

$sh P4

X is 1

X is 2

.................

X is 10

$

 

 

Цикл типа for:

for имя_ переменной [in список_значений]

Do список_команд

Done

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

 

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

list =`ls`

for val in $list

do

echo "$val"

done

echo end

 

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

 

m=0 - переменная для счетчика скопированных файлов

if [ -d $HOME/$1 ]

then echo "Каталог $1 существует"

else

mkdir $HOME/$1.

echo "Каталог $1 создан"

fi

for file in *

do

if [ -f "$file" ]

then cp "$file" $HOME/$1; m=`expr $m + 1`

fi

done

echo "Число скопированных файлов: $m"

 

Выполнение процедуры:

$sh comfil dir1

Число скопированных файлов:….

$

Здесь символ * - имеет смысл <список_имен_файлов_текущего_ каталога>

 

 

Пример процедуры PROC, выводящей на экран имена файлов из текущего каталога, число символов в имени которых не превышает заданного параметром числа.

if [ “$1” = “” ]

then

exit

fi

for nam in *

do

size = `expr $nam: ‘.*’`

if [ “$size” –le “$1” ]

then echo “Длина имени $nam $size символа”

fi

done

Вывод содержимого текущего каталога для проверки работы процедуры:

$ ls –l

total 4

drwxrwxrwx 2 lev lev 1024 Feb 7 18:18 dir1

-rw-rw-r-- 1 lev lev 755 Feb 7 18:24 out

-rwxr-xr-x 1 lev lev 115 Feb 7 17:55 f1

-rwxr-xr-x 1 lev lev 96 Feb 7 18:00 f2

$

Результаты работы процедуры:

$ PROC 2

Длина имени f1 2 символа

Длина имени f2 2 символа

$PROC 3

Длина имени out 3 символа

Длина имени f1 2 символа

Длина имени f2 2 символа

$

 

Пример. Процедура с итменем PR выводит на экран из указанного параметром подкаталога имена файлов с указанием их типа.

cd $1

for fil in *

do

If [ -d $fil]

then echo “$fil – catalog”

else echo “$fil – file”

fi

done

 

Вывод содержимого подкаталога для проверки работы процедуры:

$ ls –l pdir

total 4

drwxrwxrwx 2 lev lev 1024 Feb 7 18:18 dir1

-rw-rw-r-- 1 lev lev 755 Feb 7 18:24 out

-rwxr-xr-x 1 lev lev 115 Feb 7 17:55 f1

-rwxr-xr-x 1 lev lev 96 Feb 7 18:00 f2

 

Результаты работы процедуры:

$ PR pdir

dir1 – catalog

out – file

f1 – file

f2 – file

$

 

 

Некоторые дополнительные команды, которые могут быть использованы в процедурах:



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: