МЕТОДИЧЕСКАЯ РАЗРАБОТКА по учебной дисциплине Операционные системы ПРОГРАММИРОВАНИЕ В ОПЕРАЦИОННЫХ СИСТЕМАХ
методическая разработка на тему

Федорова Наталия Викторовна
Методическое пособие разработано для студентов специальности 230115 «Программирование в компьютерных системах», 230113«Компьютерные системы и комплексы» и 230111 «Компьютерные сети» с целью оказания методической помощи при выполнении лабораторных работ по дисциплине «Операционные системы».

Скачать:

ВложениеРазмер
Файл metod_razrabotka_programmirovanie_v_os.docx114.63 КБ

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

ДЕПАРТАМЕНТ ОБРАЗОВАНИЯ ГОРОДА МОСКВЫ

ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ

СРЕДНЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ ГОРОДА МОСКВЫ «МОСКОВСКИЙ РАДИОТЕХНИЧЕСКИЙ КОЛЛЕДЖ

ИМЕНИ А.А. РАСПЛЕТИНА»

                                                                         «УТВЕРЖДАЮ»

                                                                                    Зам. директора по УМР

                                                                                _________И.В.Микитенко

                                                              «___ » _______________ 2013 года

МЕТОДИЧЕСКАЯ РАЗРАБОТКА

по учебной дисциплине

Операционные системы

ПРОГРАММИРОВАНИЕ В ОПЕРАЦИОННЫХ СИСТЕМАХ

для учащихся

по направлению подготовки (специальности)

230115 – «Программирование в компьютерных системах»

230113«Компьютерные системы и комплексы»

230113«Компьютерные системы и комплексы»

МОСКВА

2013

Методическое пособие разработано для студентов специальности 230115 «Программирование в компьютерных системах», 230113«Компьютерные системы и комплексы» и 230111 «Компьютерные сети» с целью оказания методической помощи при выполнении лабораторных работ по дисциплине «Операционные системы».

Система

Составитель:         преподаватель МРТК им.А.А.Расплетина Федорова Н.В.

Рецензент:             преподаватель МРТК им.А.А.Расплетина Бурацкая Л.В.

Рассмотрено и утверждено на заседании  ПЦК Программирования

Протокол №___ от «___» ___________ 2013г.

Председатель комиссии______________________ Н.В.Федорова Н.В.

СОДЕРЖАНИЕ

1 Программирование в ОС MSDOS

1.1 Использование пакетных файлов

2 Программирование в ОС семейства UNIX

2.1 Программирование на SHELL. Использование командных файлов

2.2 Программирование в ОС использованием AWK»

2.3 Программирование в ОС с использованием СИ»

2.3.1 СИ-функции работы с файлами

2.3.2 СИ-функции управления процессами

2.4 Управление оперативной памятью

Список литературы


ВВЕДЕНИЕ

Методическое пособие может быть использовано студентами специальностей 230115 «Программирование в компьютерных системах», 230113«Компьютерные системы и комплексы» и 230111 «Компьютерные сети»  для изучения основных правил программирования на СИ++, SHELL, AWK при работе с операционными системами семейства UNIX, основных правил разработки командных файлов в ОС UNIX, MSDOS.

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

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

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


1 ПРОГРАММИРОВАНИЕ В ОС MSDOS

1.1 Использование пакетных файлов

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

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

Пакетные файлы можно считать особой категорией исполняемых программ. Если часто необходимо выполнять определенную последовательность действий на компьютере, то команды в порядке выполнения рекомендуется поместить в специальный пакетный файл. Исполнение файла приведет к выполнению команд. Такие файлы должны иметь тип bat (от английского слова batch – «пакетный»). Запуск пакетного файла осуществляется точно так же, как и запуск обычной исполнимой программы типа .com или .exe. Пакетный файл, в отличие от обычных исполнимых программ, содержит не машинные коды программ, а текст, который интерпретируется командным процессором DOS. Строки этого текста могут представлять собой:

- встроенные команды DOS;

- обращения к исполнимым программам;

- вызовы других пакетных файлов;

- специальные команды для управления выдачей на экран;

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

- метки.

В пакетных файлах могут использоваться формальные параметры от %1 до %9. Формальный параметр принимает фактическое значение тех данных, которые указываются в командной строке после имени пакетного файла. Пример:

@echo off

cls

type %1

pause

При запуске данного пакетного файла следует указать в командной строке имя файла для просмотра. Вместо %1 будет подставлено имя этого файла с последующим выводом на экран содержимого файла в результате выполнения команды type.

В пакетных файлах DOS могут фигурировать специальные команды, предназначенные для создания нетривиальных управляющих последовательностей. К ним относятся:

- GOTO – безусловный переход (на метку);

- IF – проверка условия и ветвление;

- FOR – управление повторным выполнением команд;

- SHIFT – сдвиг списка формальных параметров.

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

Команда GOTO. Команда GOTO позволяет передавать управление на метку и тем самым осуществлять повторное исполнение участков командного файла или, наоборот, обходить некоторые участки (это имеет смысл в сочетании с командой ветвления IF). Пример:

echo off

:m1


echo вывод на принтер файла

echo Для остановки нажмите ctrl+break

copy %1 prn

pause

goto m1

В данном примере вторая строка содержит метку m1 (признаком метки является двоеточие в начале строки), а последняя строка – команду перехода на эту метку. Четыре команды внутри повторяемого участка командного файла служат для выдачи на экран поясняющих сообщений (команды ECHO) и копирования на принтер файла, имя которого подставляется вместо формального параметра %1. Команда PAUSE приостанавливает исполнение, чтобы пользователь имел возможность осмотреться и прервать работу или продолжить ее дальше. Допустим, пользователь дает с терминала команду: A:\>pr docum.doc. Начинается циклическое исполнение файла pr.bat с фактическим параметром docum.doc. На принтер начнут выдаваться одна за другой копии этого текстового файла, прерываемые паузами после каждой очередной копии.

Команда IF. Команда IF позволяет проверять условие и выполнять ветвление в зависимости от результата его проверки. Команда IF имеет три формата.

Формат 1. Проверка кода завершения какой-либо программы, сработавшей перед оператором IF.

Используется конструкция следующего вида:

IF ERRORLEVEL

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

Формат 2. Проверка наличия файла в каталоге. В этом случае начало оператора IF имеет вид:

IF EXIST <расширенное имя файла>

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

Формат 3. Сравнение двух строк, которые, в частности, могут задаваться через формальные параметры. Соответствующая конструкция может иметь вид:

IF % == <текстовая строка>

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

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

@echo off

if %1 == a goto end

echo not

exit

pause

:end


echo okey

Введите в командной строке proba.bat a или proba.bat b. Убедитесь в исполнении файла.

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

Спецификация команды:

for %%<переменная> in <значение> do <команда>

Пример:

for %%a in *.txt do type %a

Осуществляется просмотр содержимого файлов с расширением txt текущего каталога.

Команда SHIFT. Команда SHIFT вызывает сдвиг списка формальных параметров относительно списка фактических параметров. Так, если в командном файле фигурируют формальные параметры %1 и %2, а в обращении к командному файлу – фактические параметры A, B, C, D, то сначала соответствие формальных и фактических параметров выглядит следующим образом:

%1=A %2=B

Однократное применения команды SHIFT дает следующее соответствие:


%1=B %2=C

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

%1=C %2=D

Пример:

:begin

type %1

shift

echo Enter ctrl+break for exit

goto begin

Практическое задание к выполнению лабораторной работы на тему «Пакетные файлы MSDOS»

В каталоге C:\BAT создать пакетные файлы, выполняющие следующие действия:

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

2. При выполнении пакетного файла создаются несколько txt-файлов в результате перенаправления справочной информации по некоторым командам (по выбору). Следующим действием пакетного файла является постраничный вывод на экран содержимого этих файлов (при выводе информации на экран использовать оператор for).

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

4. Осуществляется просмотр содержимого файла, полученного путем конкатенации файлов type_nc, type_win. Файл type_nc содержит отсортированную по размеру информацию о содержании каталогом C:\NC exe-файлов. Файл type_win содержит отсортированную по дате создания информацию о содержании каталогом C:\Windows exe-файлов.

5. Создается многотомный архив каталога С:\Games (или любого другого). Тома архива защищены паролем. При нажатии любой клавиши на экран постранично выводится оглавление архива.

6. Осуществляется форматирование дискеты размером 3,5» емкостью 1,44 мБт (указать количество дорожек и секторов) с последующим копированием системных файлов на дискету.

7. Осуществляется печать несколько копий одного документа (выход из цикла – ^C, ^break). Использовать формальный параметр для указания имени файла для печати. Использовать команду перехода для организации цикла. Если принтер не настроен, можно использовать команду выдачи информации не на принтер, а на экран.

8. Задача аналогична предыдущей. Осуществляется печать несколько копий одного документа. Количество копий задается в наборе оператора for.

9. Осуществляется копирование указанного в качестве формального параметра файла на дискету. Первоначально проверяется наличие параметра в командной строке.

10. При выполнении пакетного файла в качестве параметров вводится несколько файлов для удаления. В результате выполнения пакетного файла указанные файлы поочередно удаляются. Использовать команду shift для организации сдвига параметров. Имена файлов для удаления задаются с помощью формальных параметров.

11. Осуществляется проверка наличия файла. В случае, если указанный файл существует, он копируется на дискету. Использовать формальный параметр для указания файла.

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

13. Удалить найденные tmp-файлы.


2 ПРОГРАММИРОВАНИЕ В ОС СЕМЕЙСТВА UNIX

2.1 Программирование на SHELL. Использование командных файлов

Цель лабораторной работы: изучение основных возможностей языка программирования Shell с целью автоматизации процесса администрирования системы за счет написания и использования командных файлов.

Основные понятия. Командный язык Shell – язык программирования высокого уровня. На этом языке пользователь осуществляет управление компьютером. После входа в систему Вы начинаете взаимодействовать с командной оболочкой. Shell не является единственным командным языком (хотя именно он стандартизирован в рамках POSIX – стандарта мобильных систем).

Процедура языка shell. Shell – одна из многих команд Unix. Процедура языка Shell – это командный файл. Для выполнения команд необходимо текстовый файл сделать исполнимым (с помощью команды chmod).

Запуск осуществляется следующим образом:

sh имя_исполняемого_файла

Структура команд. Команды в Shell имеют следующий формат:

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

В таблице 2.1 представлены некоторые средства группировки команд, которые могут быть использованы при создании командных файлов на shell.


Таблица 2.1 – Средства группировки команд

Средства группировки

Пояснение

;

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

&

определяет асинхронное (фоновое) выполнение команд

&&

определяет выполнение последующей команды при нормальном завершении предыдущей

||

определяет выполнение последующей команды при ненормальном завершении предыдущей

Например:

k1&&k2; k3

k2 будет выполнена при успешном выполнении k1; k3 будет выполнена после любого из исходов обработки k2

k1&&{k2;k3} – k2, k3 будут выполнены при успешном выполнении k1

{k1;k2}& – в фоновой режиме будет выполняться последовательность команд k1, k2

Перенаправление данных. Символы > >> обозначают перенаправление ввода/вывода

Например, ls>file1 // команда ls сформирует список файлов текущего каталога и поместит его в файл file1

wc -l < file1 // команда wc подсчитает число строк файла file1 и выдаст эту информацию на экран

Можно сочетать перенаправления

wc -l < file1>file2 // команда wc подсчитает число строк файла file1 и выдаст эту информацию в файл file2

Shell-переменные. Определение переменной содержит имя и значение var = value. Доступ к переменной осуществляется по имени (со знаком $ перед именем)

fruit = apple (определение)


echo $ fruit (доступ)

apple (результат)

Возможна конкатенация строк

fruit = apple

fruit = pine$ fruit

echo $ fruit

pineapple

Переменная может быть:

1. Частью полного имени файла, например d = /usr/bin

2. Частью команды, например, s = «sort +b filename» //наличие пробелов требует кавычек

Предопределенные переменные языка Shell. В таблице 2.2 представлены наиболее употребительные переменные.

Таблица 2.2 – Наиболее употребительные переменные

Название

Пояснение

HOME

домашний каталог пользователя

PATH

множество каталогов, в которых ОС ищет команды

PS1

первичная подсказка

Изменение значения переменной PS1 осуществляется в login-файле. Изменение значения переменной PATH:

echo path

посмотреть

:/bin :/usr/bin

значение path

cd

домой

mkdir bin

новый каталог

echo $home

посмотреть

/users/maryann

текущий каталог

$path = :$home/bin:$path

изменение path

echo path

посмотреть

:/users/maryann/bin :/bin :/usr/bin

новое значение path


Установка переменной Shell выводом из команды

Пример 1

now =’data’

echo $now

Sun Mart 21 12:00:01 PM 2001

Пример 2

menu =’cat file’

echo $menu

text

Пример 3. Для обеспечения видимости переменной используется команда export.

1) a = b; export a

echo $a

2) d = /home/sv; export d

echo $d

3) c = ‘pwd’; export c

echo $c

Структурные операторы shell. Оператор цикла FOR. Синтаксис:

for <переменная> in <список значений>

do <список команд>

done

Пример. Пусть имеется командный файл makelist:


cat makelist

sort +1 people | pr -h Distribution | lpr //Сортировка по второму полю, печать заголовка, распечатка файла

Если вместо одного файла people имеется несколько adminpeople, hardpeople, softpeople, то необходимо повторить выполнение процедуры с различными файлами с помощью оператора for

Пример 1

for file in adminpeople, hardpeople, softpeople

do

sort +1 $file | pr -h Distribution | lpr

done

Пример 2

for file in *people

do

sort $file

done

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

Синтаксис:

if <если эта команда выполняется успешно, то>

then <выполнить все последующие команды до else или, если его нет, до fi>

[else <иначе выполнить следующие команды до fi>]

fi

Пример

if test $# -eg 0

then echo «You must give a filename»

exit 1

else sort +1 $1| …| lpr

fi

// Если значение переменной # равно нулю, выводится сообщение «You must give a filename», выполнение программы прекращается. Иначе выполняется команда сортировки данных.

Команда TEST. Эта команда применяется внутри shell-процедур.

Имеется три типа проверок: оценка числовых значений; оценка типа файла; оценка строк.

Для чисел синтаксис следующий. N op M, где N, M -числовые переменные, операция op принимает следующие значения:

-eg

равно

-ne

не равно

-gt

больше

-lt

меньше

-ge

больше и равно

-le

меньше или равно

Для файла синтаксис такой:

op filename

операция op принимает следующие значения:

-s

файл существует и не пуст

-f

файл, а не каталог

-d

файл-директория

-w

файл для записи

-r

файл для чтения

Для строк синтаксис такой:

S op R операция op принимает следующие значения:\

=

эквивалентность

!=

неэквивалентность

-z

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

-n

ненулевая длина строки


Несколько проверок могут быть объединены логическими операциями -a (and) и -o (or).

Пример 1

if test -w $2 -a -r $1

then cat $1>> $2

else echo «can not append»

fi

Пример 2

echo «Vvedite a»

read a

echo «Vvedite b»

read b

if test $a -lt $b

then

echo «Hello»

else

echo «…»

fi

Оператор цикла WHILE

Синтаксис:

while <команда>

do <команда>

done

Пример 1

n = 0

while test $n -lt 5

do

cat myfile1|lpr

n=`expr$n+1`

done

Пример 2

while test $# -gt 0

do

if test -s $1

then echo «no file $1»> $2

else sort +1 $1 …

fi

do

Оператор цикла UNTIL

Этот оператор инвертирует условие повторения по сравнению с оператором

while

until <команда>

do <команды>

done

Пока «команда» не выполнится успешно, выполнять «команды», завершаемые ключевым словом done

Пример

if test $# -eg 0

then echo «Usage …»>$2

exit

fi

until test $# -eg 0

do

if test -s $1

then echo «no file $1»>$2

else sort …

fi

shift

done

Оператор выбора CASE

Синтаксис:

case in

string1) <если string = string1, то выполнить все следующие команды до ;;> ;;

string2) <если string = string2, то выполнить все следующие команды до ;;> ;; string3) и т.д.

esac.

Пример 1

together = no

case $1 in

-t) together = yes

shift;;

-?) echo «$0: no option $1»

exit;;

esac

if test $ together = yes

then sort …

fi

Пример 2

while true

do

echo»Check menu your computer»

1) Disk space

2) Mounted file systems

3) System name

4) Who is logged in

5) Exit

«

echo «What do you want?»

read number

case $number in

1) df

;;

2) mount -t msdos dev/fd0 /mnt/floppy

;;

3) uname

;;

4) who

;;

5)break

;;

*) echo «you must enter a number (1 throught 5)»

continue

;;

esac

done

exit 0

На экране появляется меню. При выборе определенного пункта меню выполняется соответствующая команда.

Отладка процедур языка shell

1. Имеются три средства, позволяющие вести отладку процедур.

2. Размещение в теле процедуры команды echo для выдачи сообщений, являющихся трасой выполнения процедуры.

3. Опция -v (verbose – многословный) в команде Shell приводит к печати команды на экран перед ее выполнением.

4. Опция -x (execute) в команде Shell приводит к печати команды на экране по мере ее выполнения с заменой всех переменных их значениями.

Практическое задание к выполнению лабораторной работы на тему «Программирование на SHELL в ОС семейства UNIX»


1. Используя команды ECHO, PRINTF вывести информационные сообщения на экран.

2. Присвоить переменной А целочисленное значение. Просмотреть значение переменной А.

3. Присвоить переменной В значение переменной А. Просмотреть значение переменной В.

4. Присвоить переменной С значение «путь до своего каталога». Перейти в этот каталог с использованием переменной.

5. Присвоить переменной D значение «имя команды», а именно, команды DATE. Выполнить эту команду, используя значение переменной.

6. Присвоить переменной E значение «имя команды», а именно, команды просмотра содержимого файла, просмотреть содержимое переменной. Выполнить эту команду, используя значение переменной.

7. Присвоить переменной F значение «имя команды», а именно сортировки содержимого текстового файла. Выполнить эту команду, используя значение переменной.

Написать скрипты, при запуске которых выполняются следующие действия:

8. Программа запрашивает значение переменной, а затем выводит значение этой переменной.

9. Программа запрашивает имя пользователя, затем здоровается с ним, используя значение введенной переменной.

10. Программа запрашивает значения двух переменных, вычисляет сумму (разность, произведение, деление) этих переменных. Результат выводится на экран (использовать команды a) EXPR; б) ВС).,

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

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

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

14. Используя оператор FOR, отобразить содержимое текстовых файлов текущего каталога поэкранно.

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

16. Программой запрашивается год, определяется, високосный ли он. Результат выдается на экран.

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

18. В качестве аргумента командной строки указывается пароль. Если пароль введен верно, постранично отображается в длинном формате с указанием скрытых файлов содержимое каталога /etc.

19. Проверить, существует ли файл. Если да, выводится на экран его содержимое, если нет – выдается соответствующее сообщение.

20. Если файл есть каталог и этот каталог можно читать, просматривается содержимое этого каталога. Если каталог отсутствует, он создается. Если файл не есть каталог, просматривается содержимое файла.

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

22. Если файл запуска программы найден, программа запускается (по выбору).

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

24. Командой TAR осуществляется сборка всех текстовых файлов текущего каталога в один архивный файл my.tar, после паузы просматривается содержимое файла my.tar, затем командой GZIP архивный файл my.tar сжимается.

25. Написать скрипт с использованием функции, например, функции, суммирующей значения двух переменных.

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

2.2 Программирование в ОС с использованием AWK»

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

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

Утилита AWK изначально объединяла свойства утилит UNIX – sed и grep. В дальнейшем ее возможности значительно расширились. Утилита AWK была создана в 1977г, американскими авторами: Alfred V.Aho, Brian W.Kernighan и Peter J.Weinberger. Подробное описание всех возможностей утилиты AWK для UNIX дает их издание: ``The AWK Programming Language'', 1988.

AWK сканирует input (стандартный или указываемый набор файлов), и над строками, удовлетворяющими заданному образцу, выполняет указываемые действия. Строка может содержать максимально до 256 символов.

Формат:

awk [-Fc] [-f file] [files]

awk [-Fc] [prog] [files]

prog – программа, вида: <образец> <действие>

file – файл с AWK-программой

files – файлы, предназначенные для AWK-обработки.

-Fc – устанавливает разделитель полей.

Общая структура AWK-программы

Язык программирования AWK допускает использование: полей; переменных (стандартных, массивов); арифметических выражений.

Язык программирования AWK допускает использование образцов следующего вида: регулярное выражение; выражение отношения; комбинация образцов; слова BEGIN и END.

Действие в AWK определяет: последовательность предложений, разделенных ``;'' или ``\n'' (новая строка).

Предложение определяет: вывод (печать); присваивание; встроенная функция; управляющая структура.

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

На поля можно ссылаться из AWK программы следующим образом:

$1 – Первое поле;

$2 – Второе поле и т.д.

$0 – Ссылается на всю строку целиком.

Строка может содержать максимально до 100 полей.

Переменные

Значения переменных

Переменные могут интерпретироваться как числовые или строковые. Они принимают значения в зависимости от контекста, например:

x = 1, x воспринимается как число;

x = " ", x – строка;

x + "abc" – результат операции интерпретируется как число независимо от того, было ли х числом или строкой. Если строка не может быть интерпретирована как число ("abc"), то ее значение становится 0.

Строка может содержать максимально до 256 символов.

Переменные поля

Ссылки на поля $1, $2, ... могут интерпретироваться в качестве переменных, например:

$1 = "3" + $2 – первое поле принимает значение второго поля, увеличенного на 3.

$(i+1) – интерпретируется как поле, номер которого зависит от значения переменной i.

Массивы

Допускается использование массивов. Массивы не объявляются, а принимают значения из контекста, например:

x[NR] = $0 – элементу массива x, индексированному NR, присваивается обрабатываемая строка (NR – number of records – номер записи, количество записей).

x["apple"] – элементы массива могут индексироваться не числовым значением, т.е. строкой.

Арифметические выражения

Выражение включает: переменную; число; строку; встроенную функцию.

Арифметические выражения имеют вид:

Выражение < Операция> Выражение.

< Операция> : "+", "-", "*", "/", "%"

Образцы /patterns/

Регулярное выражение

Для осуществления поиска в AWK языке допускается использование регулярных выражений, определенных в описании. Дополнения к использованию регулярных выражений, допускаемые в AWK-языке:

"( )" – скобки допускаются для группирования;

" |" – указание альтернативы "или";

" + " – плюс, стоящий за регулярным выражением означает любую последовательность вхождений этого выражения, начиная с 1;

" ? " – Знак вопроса за регулярным выражением означает 0 или 1 вхождений этого выражения;

[A-Z] – Допускается сокращенная форма записи для рангов ASCII символов;

Установленный порядок выполнения операторов на одном скобочном уровне: "[] * + ? конкатенация |".

Выражение отношения

Выражение отношение может быть двух типов:

< Выражение> < Принадлежность> < Выражение>

< Выражение> < Лог. Операция> < Выражение>

Принадлежность: ~ – Содержится; !~ – Не содержится.

Лог. Операция: < , < =, ==, !=, > =, > .

Комбинация образцов

Допускается логическая комбинация образцов с использованием следующих знаков: || – ``или'', & & – ``и'', ! – ``не''.

BEGIN и END

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

Например:

BEGIN {FS = ":"} – Устанавливает разделитель полей в ":" до начала обработки строк. Эквивалентно опции "-F:" при AWK вызове.

END { print NR } – Печатает номер последней строки input, т.е. количество обработанных входных строк.

Действия

Вывод /Печать/

Формат оператора печати:

PRINT [< список выражений> ] [ > < выражение1> ]

Если в списке выражения находятся через запятую, то значения этих выражений выводятся на output (печатаются) через символ-разделитель OFS (по умолчанию пробел). Если же выражения стоят через пробел, то на печати происходит их конкатенация.

Значение < выражения1> рассматривается как имя файла. Само его присутствие означает печать в файл. Если вместо ``> '' стоит ``> > '', то это означает добавление к уже существующему файлу. Можно использовать в одной программе максимально до 10 output файлов.

Оператор форматированной печати:

PRINTF формат [,список выражений] [ > выражение1]

формат: символьная строка в двойных кавычках. Идентичен формату, используемому в функции printf в языке С. Формат может содержать:

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

esc-последовательности, представляющие неграфические символы, например, "\n" – новая строка.

спецификации для вывода аргументов, они следуют после символа ``%''. Число спецификаций должно быть равно числу аргументов. (Если оно меньше числа аргументов, то лишние аргументы игнорируются, если же больше – то это ошибка).

Присваивание

Оператор присваивания имеет вид:

< переменная> = < выражение>

Начальное значение переменной 0 или `` '' (пробел). Допускаются другие типы присваивания в соответствии с языком С: "+=","-=","*=","/=","%=".

< переменная> ++, ++< переменная> – увеличение значения переменной на 1.

< переменная> --, --< переменная> – уменьшение значения переменной на 1.

Встроенные функции

length(arg) – Функция длины arg. Если arg не указан, то выдает длину текущей строки.

exp(),log(),sqrt() – Математические функции экспонента, логарифм и квадратный корень.

int() – Функция целой части числа.

substr(s,m,n) – Возвращает подстроку строки s, начиная с позиции m, всего n символов.

index(s,t) – Возвращает начальную позицию подстроки t в строке s. (Или 0, если t в s не содержится.)

sprintf(fmt,exp1,exp2,...) – Осуществляет форматированную печать (вывод) в строку, идентично PRINTF.

split(s,array,sep) – Помещает поля строки s в массив array и возвращает число заполненных элементов массива. Если указан sep, то при анализе строки он понимается как разделитель.

Управляющие структуры

Условное предложение:

if ( < условие> ) < предложение>

\hskip 1cm [else < предложение> ]

Предложения цикла:

while ( < условие> ) < предложение>

for (< выражение> ; < условие> ; < выражение> )

\hskip 1cm < предложение>

Например:

for(i=1; i< =NF; i++) – Аналогично циклу for в языке С. NF – number of fields – номер поля, количество полей.

for (i in array) – Цикл по элементам массива. Элементы массива доступны в этом случае в случайном порядке.

break – Немедленный выход из цикла.

continue – Переход к выполнению следующего предложения.

next – Немедленный переход к анализу следующей строки.

exit – Выход из программы (на конец input).

# – Комментарий.

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

awk ‘{print $0}’ file1 – Сканируется содержимое файла file1. Печатаются все поля каждой записи.

awk ‘{print $1 «,» $2}’ file1 – Сканируется содержимое файла file1. Печатаются первое, второе поле каждой записи.

awk ‘$1==1970 {print $0}’ file1 – Сканируется содержимое файла file1. Печатаются все поля строк, удовлетворяющих заданному условию (год рождения есть 1970).

Практическое задание к выполнению лабораторной работы на тему

«ОС семейства UNIX. Сканирование текстов. Язык программирования AWK»

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

Используя команду awk:

1. Отобразить на экране всю информацию о сотрудниках из указанного файла в той последовательности, в какой она представлена в файле.

2. Отобразить на экране всю информацию о сотрудниках из указанного файла в обратной последовательности по сравнению с той, в какой она представлена в файле.

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

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

5. Отобразить все данные о конкретном сотруднике. Информацию в строке выводить с использованием двойной табуляции.

6. Отобразить фамилии сотрудников конкретного структурного подразделения.

7. Отобразить фамилии, названия СП сотрудников одного года рождения.

8. Отобразить названия СП, в которых есть сотрудники старше 1985 года рождения.

9. Определить суммарное значение по полю оклад сотрудников данной организации.

10. Определить суммарное значение по полю оклад сотрудников конкретного СП.

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

12. Задания выполнить:

а) в командной строке;

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

2.3 Программирование в ОС с использованием СИ»

2.3.1 СИ-функции работы с файлами

Цель лабораторной работы: изучение и использование СИ-функций работы с файлами.

Основные понятия. Рассмотрим основные системные вызовы, связанные с проведением операций ввода-вывода, которые наиболее часто используются в операционной системе UNIX. Ввод-вывод в ОС UNIX является крайне простой операцией и налагает на пользователя минимум ограничений.

Системный вызов ореn

Системный вызов ореn (открыть файл) имеет следующий формат:

#include

open(name, flags, mode)

char *name;

int flags, mode;

Системный вызов open открывает файл с именем name для чтения и/или записи. Режим открытия файла определяется значением параметра flags. Это значение может быть задано как результат логического сложения следующих признаков (в любой комбинации):

0_RDONLY – открыть только для чтения.

0_WRONLY -открыть только для записи.

0_RDWR – открыть для чтения и записи.

0_NDELAY – не блокировать при открытии. Если операция открытия задерживается по каким-либо причинам, например, при отсутствии готовности линии связи, процесс не приостанавливается. Возвращается код ошибки.

0_АРРЕND – открыть для дозаписи. Обычно, при открытии файла, указатель текущей позиции чтения/записи устанавливается на его начало, но, если задан режим 0_АРРЕND, этот указатель устанавливается на конец файла.

0_СRЕАТ – создать файл, если он не существует.

0_TRUNC – сократить размер файла. В режиме 0_ТRUNC, если указанный файл существует, его размер усекается до нуля.

0_ЕХСL – выдавать ошибку при попытке создания существующего файла. (Этот признак используется в сочетании с признаком 0_СRЕАТ). Режим может применяться для организации простого механизма блокировки.

В случае успешного завершения вызова Ореn, возвращается дескриптор открытого файла, иначе – значение -1 и в переменную еrrnо записывается код ошибки.

При неудачном завершении, переменная еrrnо может принимать следующие значения:

[ЕNOTDIR] – указанное имя, содержит компоненту, которая не является справочником;

[ЕNOENT] – указанный файл не существует и режим 0_СRЕАТ не был определен;

[ЕРЕКМ] – указанное имя содержит символ, отсутствующий в коде АSCП*);

[ЕLООР] – число косвенных ссылок в указанном имени превышает максимально допустимое значение;

[ЕROFS] – указанный файл содержится в файловой системе закрытой по записи и не может быть модифицирован;

[ЕTXTBSY] – попытка открыть на запись файл, содержащий загрузочный модуль выполняющейся реентерабельной программы;

[ЕАССЕS] – режим доступа указанного файла не соответствует

запросу;

[ЕFAULТ] – адрес параметра системного вызова выходит за границы адресного пространства процесса;

[ЕISDIR] Попытка открыть на запись справочник;

[ЕМFILЕ] – переполнена таблица дескрипторов открытых файлов процесса;

[ЕNXIO] – указанный файл является внешним устройством, которое в данный момент не готово к работе.

Системный вызов сrеаt

Системный вызов сrеаt (создать файл) имеет следующий формат:

сreat(name,mode)

сhar *name;

int mode;

Функция сгеаt создает новый (или подготавливает к повторной записи уже существующий) файл с именем name. Если файл еще не существует, значение параметра mode используется для формирования режимов доступа создаваемого файла, при этом учитывается значение маски режимов процесса. Значение параметра mode составляется по правилам, приведенным в описание системного вызова chmod. Если указанный файл существует, то его владелец и режим доступа остаются прежними, а файл усекается до нулевой длины. Кроме того, файл открывается для записи и возвращается его дескриптор.

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

После неудачного завершения системного вызова сгеаt переменная еrrnо может принимать следующие значения:

[ЕNOTDIR] – указанное имя содержит компоненту, которая не является справочником;

[ЕNOENТ] – задано слишком длинное или пустое имя файла, или указанный файл не существует или какой-либо из справочников, входящих в имя файла, не доступен для просмотра;

[ЕРЕКМ] – указанное имя содержит символ, отсутствующий в коде АSСП;

[ELООР] – число косвенных ссылок в указанном имени превышает максимально допустимое значение;

[ЕROFS] – попытка создания файла в файловой системе, закрытой на запись;

[ЕТХТВSУ] – попытка сократить длину файла, содержащего загрузочный модуль реентерабельной программы (разделяемый текстовый сегмент), которая в настоящей момент выполняется;

[ЕАССЕS] – режим доступа указанного файла не соответствует запросу;

[ЕFAULТ] – адреса аргументов системного вызова выходят за границы памяти, доступной данному процессу;

[ЕISDIR] – указанное имя файла является именем справочника;

[ЕМFILЕ] – переполнилась таблица открытых файлов процесса;

[ЕNXIO] – указано имя специального файла, для которого нет соответствующего устройства.

Параметр mode задается произвольно, в нем не обязательно должно быть разрешение на запись. Эта возможность используется программами, которые работают с временными файлами с фиксированными именами. Создание производится с режимом, запрещающим запись. Затем, если другая программа пытается выполнить вызов сгеаt, возвращается ошибка и программе становится известно, что в данный момент это имя использовать нельзя. Все действия, перечисленные для вызова сгеаtе, можно выполнить с помощью системного вызова ореn. Вызов сгеаtе оставлен для совместимости с ранними версиями ОС Unix.

Системный вызов read

Системный вызов геаd (чтение файла) имеет следующий формат:

read (fd, buf, nbytes)

char *buf;

int fd, nbytes;

Системный вызов read обеспечивает считывание nbytes данных в массив buf из файла с дескриптором fd. Информация читается из файла по текущему указателю позиции чтения/записи. После завершения пересылки данных значение указателя увеличивается на число считанных байт. Для некоторых файлов значение указателя позиции чтения/записи не имеет смысла (например, для терминала), тем не менее, данные передаются. При успешном завершении вызова, возвращается число считанных байт, в случае ошибки – значение -1, при достижении конца файла в процессе чтения – число 0.

При возникновении ошибки чтения, переменная еrrnо может принимать следующие значения:

[ЕВАDF] – указанный дескриптор не является дескриптором файла, открытого для чтения;

[ЕFAULТ] – адрес параметра системного вызова не входит в адресное пространство процесса;

[ЕINTR] – чтение с медленного устройства прервано до передачи данных.

Системный вызов write

Системный вызов write (запись в файл) имеет следующий формат:

write (fd, buf, nbytes)

char *buf;

int fd, nbytes;

Системный вызов write записывает nbytes данных из массива buf в файл с дескриптором fd. Информация записывается в файл по текущему указателю позиции чтения/записи. После завершения пересылки данных, значение указателя увеличивается на число записанных байт. Для некоторых файлов значение указателя позиции чтения/записи не имеет смысла, (например, для терминала), тем не менее, данные передаются.

Если статус файла, в который записывается информация, содержит признак set-UID и процесс работает в непривилегированном режиме, данный признак удаляется (в целях защиты информации). При успешном завершении вызова возвращается число записанных байт, в случае ошибки – значение -1. При возникновении ошибки, переменная еrrnо может принимать следующие значения:

[ЕВАDF] – указанный дескриптор не является дескриптором файла, открытого для записи;

[ЕРIРЕ] – попытка записи в программный канал, который никто не читает;

[ЕРIРЕ] – запись в файл типа "гнездо" в режиме S0СК_SТRЕАМ, при отсутствии соединения;

[ЕFВIG] – при записи в файл превышается допустимый размер файла;

[ЕFAULТ] – адрес параметра системного вызова не входит в адресное пространство процесса.

Системный вызов сlose

Системный вызов сlose (закрыть файл) имеет следующий формат:

аns = сlоsе (fd)

int fd;

Системный вызов сlosе удаляет дескриптор fd из таблицы дескрипторов открытых файлов процесса. Если удаленный дескриптор был последним ссылающимся на данный файл, то весь контекст работы с файлом теряется. Для обычного файла это указатель позиции чтения/записи и режим блокировки. Хотя, при завершении процесса, все открытые им файлы автоматически закрываются, число одновременно открытых файлов ограничено, поэтому данный вызов может оказаться необходимым для программ, работающих с большим количеством файлов.

При порождении нового процесса (см описание вызова fork) все его дескрипторы указывают на те же объекты, что и дескрипторы процесса-предка. После выполнения вызова ехесvе в порожденном процессе, новая программа также наследует все активные дескрипторы. Для того, чтобы сделать недоступными новой программе уже открытые файлы, соответствующие дескрипторы можно переопределить с помощью dup2 или удалить с помощью системного вызова unlink. Однако бывают ситуации, в которых уже открытые файлы могут потребоваться при неудачном завершении системного вызова execvе. В таких случаях, применение вызова fcntl обеспечивает закрытие определенных файлов после успешного старта новой программы. В случае успешного завершения, системный вызов с1оsе возвращает значение 0, иначе – значение -1 и код ошибки в переменной еrrnо. Код ошибки:

[ЕВАDF] – указанный дескриптор не является дескриптором открытого файла.

Системный вызов lsееk

Системный вызов lsееk (установка указателя чтения/записи) имеет следующий формат:

#define L_SЕТ 0 /* установка * /

# define L_INCR 1 /* смещение */

# define L_ХТND 2 /* увеличение размера файла */

long lseek (fd, offset, whence)

int fd, whence;

long offset;

Системный вызов lsееk изменяет значение указателя позиции чтения/записи дескриптора fd следующим образом: если значение параметра whence равно L_SЕТ, то указателю присваивается значение параметра, если значение параметра whence равно L_INCR, значение указателя увеличивается на значение offset, если значение параметра whence равно L_XTND, то указателю присваивается значение (offset + fsize), где fsize- размер файла.

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

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

При возникновении ошибки, возвращается значение -1 и код ошибки в переменной еrrnо, которая может принимать следующие значения:

[ЕВАDF] – некорректный дескриптор файла;

[ЕSРIРЕ] – дескриптор относится не к файлу, а к программному каналу или файлу типа "гнездо";

[ЕINVAL] – недопустимое значение параметра.

Дополнительную информацию смотри в методическом пособии «СИ++ для UNIX», лекциях по дисциплине «Системное программное обеспечение».

Практическое задание к выполнению лабораторной работы на тему «СИ-функции работы с файлами»

2.3.2 СИ-функции управления процессами

Цель лабораторной работы: изучение системных функций, обеспечивающих управление процессами в среде ОС семейства UNIХ: их создание, удаление, изменение приоритетности и т.п.

Основные понятия

Системный вызов fork

Системный вызов fork (порождение нового процесса) имеет следующий формат:

pid = fork()

int pid;


Системный вызов fork служит для создания нового процесса. Новый процесс (процесс-потомок) является полной копией процесса-предка, за исключением того, что процесс-потомок имеет свой уникальный идентификатор процесса (РID). Поскольку новый процесс сам может выступать в качестве порождающего, его идентификатор процесса-предка (РРID), естественно, отличается от соответствующего идентификатора породившего его процесса.

Новый процесс имеет собственную копию таблицы дескрипторов открытых файлов, но эти дескрипторы ссылаются на те же самые файлы, что и дескрипторы процесса-предка, и имеют с ним общие указатели позиций чтения/записи. Так, при выполнении операции 1sееk в порожденном процессе, может измениться и позиция чтения/записи файла в процессе-предке. Это свойство, в частности, используется командными языками SН СSН для переопределения файлов стандартного ввода/вывода и организации конвейеров команд. Счетчики использованных ресурсов порожденного процесса инициализируются нулевыми значениями. В случае успешного завершения, системный вызов fork возвращает значение 0 порожденному процессу и идентификатор нового процесса – породившему. При неудачном завершении вызова возвращается значение -1.

Системный вызов wait

Системный вызов wait (ожидание завершения процесса-потомка) имеет следующий формат:

pid = wait (status)

int pid;

int *status;

pid = wait(0)

int = pid;


Системный вызов wait задерживает вызвавший его процесс до поступления сигнала или завершения одного из порожденных им процессов. Если какой-нибудь порожденный процесс завершился в период времени с момента последней выдачи команды wait производится немедленный возврат. Если порожденные процессы отсутствуют, производится немедленный возврат с установкой бита ошибки (соответственно, с возвратом -1). При нормальном возврате, системный вызов wait получает идентификатор завершившегося порожденного процесса. В случае нескольких порожденных процессов нужно произвести несколько вызовов wait , чтобы отследить признаки завершения всех порожденных процессов. При успешном завершении вызова wait , значение status всегда не равно нулю и содержит код возврата и статус завершения порождённого процесса. Если порождающий процесс завершается, не ожидая своих потомков, их наследует стартовый процесс (РID=1). Вызов автоматически перезапускается, если процесс получает сигнал во время ожидания своих потомков. При нормальном завершении выдается идентификатор завершившегося процесса. В случае ошибки – значение -1 и код ошибки в переменной errnо.

Системный вызов exit

Системный вызов exit (завершить процесс) имеет следующий формат:

exit (arg)

int arg;

Параметр arg имеет смысл, определенный в описании вызова wait.

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

Ниже приводится пример использования системных вызовов fork, wait, exit

main ()

{

int pid, status, died;

switch (pid=fork()) /* порождаем новый процесс */

{

саsе -1: /* аварийное завершение */

printf («Can’t fork\n»);

ехit(-1);

саsе 0: /* процесс-потомок */

рrintf («I am the child\n»);

exit (3);

default: /* процесс предок ожидает окончание процесса-потомка */

died = wait (&status);

}

printf («Child was %d\n», pid);

printf (« %d died \n», died);

printf («Exit value %d\n», status>>8);

printf («Exit status %d\n», status &0377);

exit (0);

}

Системные вызовы ехес1, ехес1е, ехесv и ехесvе

Системные вызовы ехес1, ехес1е, ехесv и ехесvе (выполнить файл) имеют форматы:

execl (name, arg0, arg1, arg2, …, 0)

char *name;

char *arg0, *arg1, *arg2, …

execle (name, arg0, arg1, arg2, …, 0, envp)

char *name;

char *arg0, *arg1, *arg2, …

charn *envp[ ];

execv (name, argv)

char *name, *arg[ ];

execve (name, argv, envp)

char *name, *arg[ ], *envp[ ];

Системные вызовы ехес1, ехес1е, ехесv и ехесvе заменяют программу текущего процесса. Новая программа загружается из файла с именем namе, который либо является исполняемым, либо содержит интерпретируемую программу.

Исполняемый файл должен иметь соответствующий формат. Значения передаваемых параметров содержатся:

- для системных вызовов ехес1 и ехес1е – в списке указателей на строки аrg0, arg1...;

- для системных вызовов ехесv и ехесvе – в массиве argv, в виде текстовых строк.

По принятому в системе UNIX соглашению, программе должен передаваться хотя бы один параметр – имя этой программы. Обычно, в качестве имени программы используется базовое (без указания "пути") имя файла name.

Массив envp содержит имена и значения макропеременных среды процесса. Новая программа наследует все открытые файлы, за исключением тех, для которых установлен флаг с1оsе-оn-ехес. Все сигналы, которые игнорировались до выполнения вызовов ехес1, ехес1е, ехесv и ехесvе, будут игнорироваться и после их выполнения. Однако, все. установленные ранее варианты реакций на сигналы заменяются на стандартные.

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

Если статус файла с именем name содержит признак set-UID, то при выполнении новой программы изменяются права доступа процесса, т.е. эффективные идентификаторы процесса заменяются на значение идентификаторов владельца файла с именем name. Когда программа начинает выполняться, она вызывается следующим образом:

main (argc, argv, envp)

int argc;

char **argv, **envp;

где argc – количество аргументов в массиве argv, а argv – массив символьных указателей на сами аргументы.

Возврат из системных вызовов ехес1, ехес1е, ехесv, ехесvе всегда означает ошибку. При этом возвращается значение -1 и код ошибки в переменной еггnо. Если данный процесс выполняется в привилегированном режиме, то его полномочия не изменяются, даже если статус файла содержит признак set UID (set-GID).

Ниже приводится пример использования системных вызовов fork, wait, exit, execl.

main()

{

int pid, status;

switch(pid=fork()) /* порождаем новый процесс */

{

case -1: /* аварийное завершение */

printf («Can’ t fork\n»);

exit(1);

case 0: /* процесс-потомок */

printf («I am the child\n»);

execl («/bin/echo», «echo», «Hello mike!», 0);

/* запускаем команду echo «Hello mike!» */

printf («Exec error\n»); /* процесс предок */

wait (&status);

/* ожидаем завершение процесса-потомка */

}

/* Процесс-отец выводит на экран код завершения и статус завершения

процесса-потомка */

printf («Exit value %d\n», status>>8);

printf («Exit status %d\n, status & 0377);

exit(0);

}

Системный вызов getpid

Системный вызов getpid возвращает значение идентификатора текущего процесса. Системный вызов getpid (запрос идентификатора текущего процесса) имеет следующий формат:

int getpid( )

Системные вызовы getgid, getegid

Системные вызовы getgid, getegid (запрос идентификатора группы) имеют форматы:

int getgid( )

int getegid( )

Вызов getgid возвращает реальный идентификатор группы текущего процесса, а вызов getegid – эффективный идентификатор группы. Реальный идентификатор группы определяется при регистрации в системе. Эффективный идентификатор определяет дополнительные права доступа при выполнении программы в режиме set-GID (установка идентификатора группы владельца выполняемого файла).

Системные вызовы getuid, geteuid

Системные вызовы getuid, geteuid (запрос идентификатора пользователя) имеют следующие форматы:

int getuid ( )

int geteuid ( )

Системный вызов getuid возвращает реальный идентификатор пользователя для текущего процесса, a geteuid возвращает эффективный идентификатор пользователя. Реальный идентификатор пользователя совпадает с идентификатором, под которым пользователь зарегистрирован в системе. Эффективный идентификатор определяет права доступа пользователя в текущий момент. Такой механизм позволяет программе, работающей в режиме set-UID (установка прав доступа владельца объектного файла), определять, кто ее вызвал.

Системный вызов setgid

Системный вызов setgid (установить реальный идентификатор группы процесса) имеет формат:

setgid (rgid) int rgid;

Системный вызов setgid устанавливает идентификатор группы текущего процесса в соответствии с значением параметра rgid. Изменять реальный идентификатор группы можно только в процессе, работающем в привилегированном режиме. В обычном режиме допускает только замена эффективного идентификатора на значение соответствующее реальному идентификатору группы процесса. При успешном завершении, возвращается значение 0, иначе -значение -1 и код ошибки в переменной еrrnо. Код ошибки может принимать значение

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

Системный вызов setuid

Системный вызов setuid (установить реальный идентификаторы пользователя) имеет следующий формат:

setuid (ruid) int ruid;

Системный вызов setuid устанавливает текущему процессу реальный идентификатор пользователя в соответствии со значением параметра ruid. Изменять реальный идентификатор пользователя можно только в процессе, работающем в привилегированном режиме. В обычном режиме допускается только замена эффективного идентификатора на значение, соответствующее реальному идентификатору. При успешном завершении вызова, возвращается значение О, иначе – значение -1 и код ошибки в переменной еrrnо.

Код ошибки:

[EPERM] – текущий процесс не является привилегированным, и были специфицированы изменения, отличные от замены эффективного идентификатора на реальный.

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

main ( )

{

int pid,uid, gid;

int euid, egid;

pid = getpid();

uid •= getuid();

gid = getgid;

euid = geteuid();

egid = getegid();

printf("\tProcess: PID = %d\n", pid);

printf («uid = %d gid = %d\n", uid, gid);

printf("euid = %d egid = %d\n", euid, egid);

}

Системный вызов nice

Системный вызов nice (установить процессу приоритет) имеет следующий формат:

nice (incr)

Системный вызов nice устанавливается текущему процессу новый приоритет, равный текущему приоритету плюс значение аргумента incr. Значение аргумента incr должно лежать в определенном диапазоне, конкретные границы которого зависят от версии ОС UNIX.

UNIX 7. Диапазон значений incr лежит в пределах от -20 до 20. Отрицательное приращение может задавать только привилегированный пользователь.

UNIX System V. Диапазон значений incr лежит в пределах от 0 до 39. Приращения, выходящие за границы этого диапазона, уменьшаются до граничных значений. Чем выше значение аргумента incr, тем ниже устанавливаемый приоритет.

При успешном завершении вызова, возвращается новое значение приоритета минус 20, иначе – значение -1 и код ошибки в переменной еrrnо.

Код ошибки:

[EPERM] Значение incr не лежит в пределах установленного диапазона и эффективный идентификатор владельца процесса не является идентификатором суперпользователя.

Приведенная ниже программа является исходным текстом команды nice UNIX версии System V (вызова какой-либо команды на выполнение с измененным приоритетом):

nice {приращение приоритета} команда

#inc1ude

#include

main (argc, argv) int argc; char *argv [];

{

int nicarg = 10; /* приращение приоритета по умолчанию */

extern errno;

/* Разбираем аргументы команды */

if(argc > 1 && argv[l][0] = ‘-‘) { /* если задано приращение приоритета */

register char *p = argv[l];

if(*++p != ‘-‘) --р;

whi1e(*++p)

if(!isdigit(*p)) { /* указано не числовое значение */

fprintf(stderr, "nice: argument must be numeric.\n");

exit(2);

}

nicarg == atoi (&argv[l] [1]);

/* в переменной nicarg записываем значение приращения приоритета */

argc--;

argv++;

}

if (argc < 2) { /* если не задана команда */

fprintf(stderr, "nice: usage: nice [-num] command\n");

exit(2);

}

nice(nicarg); /* изменяем приоритет процесса */

execvp(argv [1], &argv[l]); /* выполняем команду */

fprintf(stderr. "%s: %d\n", argv[l], errno);

/* если ошибка при запуске команды, то печатаем переменную errno */

exit(2);

 }

Дополнительно: Для просмотра запущенных в системе процессов используется команда ps, команда top делает моментальный снимок запущенных в системе процессов, команда nice позволяет изменить приоритетность процесса, команда kill служит для уничтожения процесса.

Практическое задание к выполнению лабораторной работы на тему «СИ. Управление процессами»

1. Просмотреть запущенные в системе процессы.

2. Просмотреть запущенные в системе процессы с указанием их идентификаторов,

3. На втором терминале запустить редактор vi.

4. Определить идентификатор этого процесса.

5. Войти в систему непривилегированным пользователем на третьем терминале.

6. Уничтожить данный процесс.

7. Написать на shell сценарий. Меню выбора: 1 – Просмотр процессов. 2 – Выход. Запуск сценария обеспечивает просмотр запущенных в системе процессов.

8. Написать СИ-программу с использованием функций fork(), execl(), wait(), exit(). Откомпилировать программу и запустить на выполнение.

2.4 Управление оперативной памятью

Цель лабораторной работы: изучение возможностей языка программирования СИ, СИ++ для обращения к ячейкам оперативной памяти, управления ОП.

Основные понятия. Указатели на простые переменные

Указатель – это адрес памяти, распределяемой для размещения идентификатора (в качестве идентификатора может выступать имя переменной, массива, структуры, строкового литерала). В том случае, если переменная объявлена как указатель, то она содержит адрес памяти, по которому может находиться скалярная величина любого типа. При объявлении переменной типа указатель, необходимо определить тип объекта данных, адрес которых будет содержать переменная, и имя указателя с предшествующей звездочкой (или группой звездочек). Формат объявления указателя: спецификатор-типа [модификатор] * описатель

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

В качестве модификаторов при объявлении указателя могут выступать ключевые слова const, near, far, huge. Ключевое слово const указывает, что указатель не может быть изменен в программе. Размер переменной объявленной как указатель, зависит от архитектуры компьютера и от используемой модели памяти, для которой будет компилироваться программа. Указатели на различные типы данных не обязательно должны иметь одинаковую длину.

Для модификации размера указателя можно использовать ключевые слова near, far, huge.

Примеры:

unsigned int * a; // переменная а представляет собой указатель

// на тип unsigned int (целые числа без знака)

double * x; // переменная х указывает на тип данных с

// плавающей точкой удвоенной точности //

char * fuffer ; // объявляется указатель с именем fuffer,

// который указывает на переменную типа char

double nomer;

void *addres;

addres = & nomer;

(double *)addres ++;

Переменная addres объявлена как указатель на объект любого типа. Поэтому ей можно присвоить адрес любого объекта (& – операция вычисления адреса). Однако, как было отмечено выше, ни одна арифметическая операция не может быть выполнена над указателем, пока не будет явно определен тип данных, на которые он указывает. Это можно сделать, используя операцию приведения типа (double *) для преобразования addres к указателю на тип double, а затем увеличение адреса.

const * dr;

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

unsigned char * const w = &obj.

Переменная w объявлена как константный указатель на данные типа char unsigned. Это означает, что на протяжении всей программы w будет указывать на одну и ту же область памяти. Содержание же этой области может быть изменено.

Указатель на величину одного типа может быть преобразован к указателю на величину другого типа. Однако результат может быть не определен из-за отличий в требованиях к выравниванию и размерах для различных типов.

Указатель на тип void может быть преобразован к указателю на любой тип, и указатель на любой тип может быть преобразован к указателю на тип void без ограничений. Значение указателя может быть преобразовано к целой величине. Метод преобразования зависит от размера указателя и размера целого типа следующим образом:

- если размер указателя меньше размера целого типа или равен ему, то указатель преобразуется точно так же, как целое без знака;

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

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

- если целый тип того же размера, что и указатель, то целая величина просто рассматривается как указатель (целое без знака);

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

Массивы и указатели на массивы

С++ и С интерпретируют имя массива как адрес его первого элемента. Таким образом, если x – массив, то выражения &x[0] и x эквивалентны. В случае матрицы – назовем ее mat – выражения &mat[0][0] и mat также эквивалентны.

С++ позволяет использовать указатели для обращения к разным элементам массива. Когда Вы вызываете элемент x[i] массива x , то выполняются две задачи: получит базовый адрес массива, т.е. узнать где находится первый элемент массива и использовать i для вычисления смещения базового адреса массива. Фактически, если есть указатель ptr на базовый адрес массива, т.е.

prt = x;

то можно записать :

адрес элемента x[i] = адрес x + i * sizeof(базовый тип)

или

адрес элемента x[i] = ptr + i * sizeof(базовый тип)

В С++ это записывается более коротким образом

адрес элемента x[i] = ptr + i

При последовательном обращении к элементам массива можно использован метод инкремента/декремента указателя, т.е. операцию ++ и --, например

ptr++

a = * ptr++

a = * (ptr--)

Указатели на структуры

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

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

structPtr -> aMember

где structPtr -указатель на структуру, aMember – элемент структуры.

Пример:

struct point

{

double x;

double y;

};

point p;

point* ptr = & p;

ptr->x = 23.3;

ptr->y = ptr->x + 12.3;

Динамическое распределение ОП

Операции new и delete. Существует много приложений, в которых необходимо создавать новые переменные и динамически распределять для них память во время выполнения программы. В языке С для этого имеются функции динамической памяти, такие как malloc, calloc, free. В С++ введены новые операции – new и delete, которые лучше контролируют тип создаваемых динамических данных. К тому же эти операции работают с конструкторами и деструкторами ( раздел объектно-ориентированное программирование).

Операции new и delete имеют следующий синтаксис:

указатель = new тип;

delete указатель;

Операция new возвращает адрес динамически распределенной переменной. Операция delete освобождает динамически распределенную память, на которую ссылается указатель.

Если динамическое распределение памяти с помощью операции new потерпело неудачу, оно выбрасывает исключение типа xalloc, объявленное в заголовочном файле EXCEPT.H, поэтому часто динамическое распределение памяти осуществляется внутри блока try. Пример:

try

{

int *pint;

pint = new int;

*pint = 33;

cout << «Указателю выделена память и в ней хранятся данные» << *pint << endl;

delete pint;

}

catch (xalloc&)

{

cout << «Ошибка при выделении памяти» << endl;

Практическое задание к выполнению лабораторной работы на тему «СИ++. Управление оперативной памятью»

1. Написать программу, в которой инициализация переменных различного типа осуществляется с помощью указателей. Значения переменных выводятся на экран.

2. Написать программу, определяющую минимальное, максимальное значения элементов одномерного массива. Элементы массива вводятся с клавиатуры с использованием указателей.

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

4. Написать программу, суммирующую элементы одномерного массива. Элементы массива вводятся с клавиатуры. Ввод данных, обращение к элементам массива осуществляется с помощью указателей.

5. Отсортировать элементы массива. Ввод данных осуществляется с использованием указателей.

6. Написать программу с использованием переменной типа структура. Ввод/вывод, обращение к элементам структуры осуществляется с помощью указателей.

7. Написать программу с использованием операций new, delete (например, просуммировать элементы массива, память под массив распределить динамически).


КОНТРОЛЬНЫЕ ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ

1. Что изучает курс «Системное программное обеспечение».

2. Основной принцип модульного программирования.

3. Почему в системном программировании используется язык СИ?

4. Исходный код, объектный код, исполняемый код. Что это такое?

СИ++:

5. Как определить константы с использованием директивы #define?

6. Как определить формальные константы?

7. Как определить размер данных, занимаемых переменной?

8. Как обратиться к элементу массива?

9. Как объявить двумерный массив?

10. Как объявить массив и присвоить начальные значения для матрицы?

11. Какие бывают форматы объявления перечисления?

12. Что такое структура?

13. Какой синтаксис имеет определение структуры? Приведите пример определения структуры.

14. Приведите пример определения экземпляра структуры с использованием тега.

15. Как обратиться к элементу структуры? Приведите пример.

16. Чем отличается объединение от структуры с точки зрения использования памяти?

17. Приведите пример объединения.

18. Приведите пример инициализации составного объекта: структуры, объединения.

19. Для чего используются указатели?

20. Какой синтаксис объявления указателя? Приведите пример объявления указателя.

21. Приведите пример присвоения указателю конкретного значения.

22. Приведите пример объявления указателя на структуры и его использования в тексте программы.

23. Для чего в СИ используется ключевое слово typedef?

24. Что такое функция?

25. Чем функция main отличается от других функций?

26. Что находится в заголовочных файлах?

27. Каким образом они подключаются к программе?

28. Что происходит, если выполнение функции не заканчивается командой return?

29. Данные какого типа не может возвращать функция?

30. Какой тип используется для функции, не возвращающей значения?

31. Что такое список формальных параметров?

32. Что такое спецификатор типа функции?

33. Что содержит тело функции?

34. Что такое рекурсивная функция?

35. Могут ли передаваться данные функции main?

36. Для чего используются глобальные внешние переменные?

37. Что такое время жизни объекта?

38. Что такое область видимости объекта?

39. Какие бывают спецификаторы класса памяти? Чем они отличаются?

40. Чем отличается использование локальных и глобальных переменных?

41. Что такое директивы препроцессора?

42. Что такое макроподстановки? Приведите пример.

43. Что такое встроенные функции?

44. Классы. Пример объявления.

45. Конструкторы. Пример объявления.

46. Деструкторы. Пример объявления.

47. Наследование. Пример объявления производного класса.

48. Системные вызовы creat, read, open, write, close. Примеры использования.

49. Системные вызовы fork, execl, wait, nice, exit. Примеры использования.


СПИСОК ЛИТЕРАТУРЫ

1. Герхард Франкен, Сергей Молявко MS DOS для пользователя. – Киев, 1993.

2. Теренс Чан Системное программирование на СИ++ для Unix. / Под ред. Коломыцева, Киев, 1997.

3. Э. Немет, Г. Снайдер Unix. Руководство системного администратора. – Киев: BHV, 1997.

4. Дегтярев Е.К. Введение в Unix. – М.: Память, 1992.

5. Свиридов С.В. Системные вызовы ОС UNIX. – М.: Память, 1992.

6. Страуструп Б. Язык программирования СИ++/ Пер с англ. – М.: Радио и связь, 1991.

7. Дунаев С. UNIX-сервер. Настройка, конфигурирование, работа в операционной среде, Internet-возможности: в 2-х томах. Том 1. – М.: Диалог-МИФИ, 1999.

8. Дунаев С. UNIX-сервер. Настройка, конфигурирование, работа в операционной среде, Internet-возможности: в 2-х томах. Том 2. – М.: Диалог-МИФИ, 1999.

9. Шамер Л., Негус К. UNIX (серия «Без проблем») / Пер. с англ. – М.: Бином, 1998.

10. Д. Такет, С. Барнет Специальное издание. Использование LINUX / Пер. с англ.-4-е изд. – К.:, Н.:, СПб.: Издательский дом «Вильямс», 1999.

Размещено на Allbest.ru

Программирование в ОС        Федорова Н.В.


По теме: методические разработки, презентации и конспекты

Учебно-методический комплекс учебной дисциплины "Иностранный язык" для подготовки по специальности СПО 260807"Технология продукции общественного питания"

Учебно -методический комплекс учебной дисциплины" Иностранный язык" предназначен для подготовки студентов 2-4 курса по специальности СПО "Технология продукции общественного питания" к самостоятельным ...

Учебно-методический комплекс учебной дисциплины "Иностранный язык" для подготовки по специальности СПО 260807"Технология продукции общественного питания"

Учебно -методический комплекс учебной дисциплины" Иностранный язык" предназначен для подготовки студентов 2-4 курса по специальности СПО "Технология продукции общественного питания" к самостоятельным ...

Методические рекомендации учебной дисциплины «Основы технического черчения» по выполнению внеаудиторной самостоятельной работы профессии35.01.13 «Тракторист- машинист сельскохозяйственного производства».

Методические  рекомендации  учебной дисциплины  «Основы технического черчения»  по выполнению  внеаудиторной самостоятельной работы разработаны на основе Федерального государс...

Учебно-методическое обеспечение учебной дисциплины Прикладная электроника

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

Комплект контрольно-оценочных средств по учебной дисциплине Объектно-ориентированное программирование основной профессиональной образовательной программы по специальности СПО 230401 Информационные системы (по отраслям)

Комплект контрольно-оценочных средств разработан на основе Федерального государственного образовательного стандарта среднего  профессионального образования по специальности СПО 230401 Инфор...

Инновационные образовательные ресурсы в методическом обеспечении учебной дисциплины «Информатика и ИКТ»

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

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

Рассматриваются такие вопросы, как:1. Что такое методическая деятельность?2. Виды методической деятельности.3. Виды методических умений.4. И другое....