ЛАБОРАТОРНАЯ РАБОТА №1 УПРАВЛЕНИЕ ОС LINUX, ИНТЕРПРЕТАТОР BASH
Цель работы – изучить основные объекты, команды, типы данных и операторы управления интерпретатора BASH; создать скрипт-файл.
Теоретическая часть
Bash - это sh-совместимый интерпретатор командного языка, выполняющий команды, прочитанные со стандартного входного потока или из файла. Скрипт-файл – это обычный текстовый файл, содержащий последовательность команд bash, для которого установлены права на выполнение. Пример скрипта, выводящего содержимое текущего каталога на консоль и в файл:
#!/bin/bash
Dir
dir > 1.txt
Следующие переменные используются командным интерпретатором.
$0,$1,$2,$3… | Значения аргументов командной строки при запуске скрипта. Где $0-имя самого файла скрипта, $1- первый аргумент, $2- второй аргумент, и т.д. | ||||
$@ | Все аргументы командной строки | ||||
$? | Код возврата последней команды | ||||
Пример простого скрипта, выводящего на консоль и в файл содержимое каталога, где имя каталога передаётся скрипту в качестве аргументов при запуске:
Запуск скрипта: >./home/stud 1.sh
Скрипт:
#!/bin/bash
dir $1
dir $1 > 1.txt
Можно создать собственную переменную и присвоить ей значение:
A=121
A=”121”
let A=121
let “A=А+1”
Вывод значения на консоль: echo $A
Проверка условия: test[expr]
где expr: а) для строк: S1 = S2S1 содержит S2
S1 != S2S1 не содержит S2
-n S1 если длина S1 >0
-z S1 если длина S1 =0
б) целые i1и i2
i1 – ge i2
i1 – gt i2
i1 – ie i2
i1 – et i2
i1 – nt i2
в) файлы
-d name_file является ли файл каталогом
-f name_file является ли файл обычным файлом
-r name_file доступен ли файл для чтения
-s name_file имеет ли файл ненулевую длину
-w name_file доступен ли файл для записи
-x name_file является ли файл исполняемым
г) логически операции
!exp логическое отрицание (не)
exp1 –a exp2 умножение условий (и)
exp1 –o exp2 сложение условий (или)
Проверка условия: if [expr ]
then com 1 Если условие expr=true то команда
…
(elif expr2
…
)
Else
…
fi
Проверка нескольких условий: case string1 in
Str 1)
…
; ;
Str 2)
…
; ;
Str 3)
…
; ;
*) // default
…
; ;
Esac
Функция пользователя: fname2 (arg1,arg2...argN)
{
commands
}
Организация циклов:
1. for var1 in list
do
…
Done
2. while exp
…
End
3. until exp // аналог do-while
do
…
Done
Порядок выполнения работы
1. Изучить теоретическую часть лабораторной работы.
2. В консольном режиме создать, используя команды из табл.1, в домашней папке подкаталог: /номер_группы/ФИО_студента, где в дальнейшем будут храниться все файлы студента. Перейти в корневой каталог и вывести его содержимое используя команды dir и ls –all , проанализировать различия.
3. Проверить действие команд ps, ps –x, top, htop. Найти в справочной системе используя команду man справку по функциям fprintf, fputc и команде ls.
4. В текстовом редакторе joe (вызов: joe 1.c) написать программу 1.c, выводящую на экран фразу “HELLO SUSE Linux”. Компилировать полученную программу компилятором gcc: gcc 1.c –o 1.exe. Запустить полученный файл 1.exe на выполнение: ./1.exe
5. Написать скрипт, выводящий на консоль и в файл все аргументы командной строки.
6. Написать скрипт, выводящий в файл (имя файла задаётся пользователем в качестве первого аргумента командной строки) имена всех файлов с заданным расширением (третий аргумент командной строки) из заданного каталога (имя каталога задаётся пользователем в качестве второго аргумента командной строки).
7. Написать скрипт, компилирующий и запускающий программу (имя исходного файла и exe- файла результата задаётся пользователем в качестве аргументов командной строки). В случае ошибок при компиляции вывести на консоль сообщение об ошибках и не запускать программу на выполнение.
Варианты индивидуальных заданий
1. Написать скрипт для поиска файлов заданного размера в заданном каталоге (имя каталога задаётся пользователем в качестве третьего аргумента командной строки). Диапазон (мин.- мах.) размеров файлов задаётся пользователем в качестве первого и второго аргумента командной строки.
2. Написать скрипт с использованием цикла for, выводящий на консоль размеры и права доступа для всех файлов в заданном каталоге и всех его подкаталогах (имя каталога задается пользователем в качестве первого аргумента командной строки). На консоль выводится общее число просмотренных файлов.
3. Написать скрипт для поиска заданной пользователем строки во всех файлах заданного каталога и всех его подкаталогов (строка и имя каталога задаются пользователем в качестве первого и второго аргумента командной строки). На консоль выводятся полный путь и имена файлов, в содержимом которых присутствует заданная строка, и их размер. Если к какому-либо каталогу нет доступа, необходимо вывести соответствующее сообщение и продолжить выполнение.
4. Написать скрипт поиска одинаковых по содержимому файлов в двух каталогов, например, Dir1 и Dir2. Пользователь задаёт имена Dir1 и Dir2 в качестве первого и второго аргумента командной строки. В результате работы программы файлы, имеющиеся в Dir1, сравниваются с файлами в Dir2 по их содержимому. На экран выводятся число просмотренных файлов и результаты сравнения.
5. Написать скрипт, находящий в заданном каталоге и всех его подкаталогах все файлы, владельцем которых является заданный пользователь. Имя владельца и каталог задаются пользователем в качестве первого и второго аргумента командной строки. Скрипт выводит результаты в файл (третий аргумент командной строки) в виде полный путь, имя файла, его размер. На консоль выводится общее число просмотренных файлов.
6. Написать скрипт, находящий в заданном каталоге и всех его подкаталогах все файлы заданного размера. Диапазон (мин.- мах.) размеров файлов задаётся пользователем в качестве первого и второго аргумента командной строки. Скрипт выводит результаты поиска в файл (третий аргумент командной строки) в виде: полный путь, имя файла, его размер. На консоль выводится общее число просмотренных файлов.
7. Написать скрипт подсчитывающий суммарный размер файлов в заданном каталоге и всех его подкаталогах (имя каталога задаётся пользователем в качестве аргумента командной строки). Скрипт выводит результаты подсчёта в файл (второй аргумент командной строки) в виде каталог (полный путь), суммарный размер файлов число просмотренных файлов.
ЛАБОРАТОРНАЯ РАБОТА №2 РАБОТА С ФАЙЛАМИ И КАТАЛОГАМИ ОС UNIX
Цель работы – изучить основные системные вызовы и функции в ОС UNIX для работы с файлами и каталогами.
Теоретическая часть
Функция int main( int argc[] , char *argv[ ] [, char *envp[ ] ] );
Данное объявление позволяет удобно передавать аргументы командной строки и переменные окружения. Определение аргументов:
argc - количество аргументов, которые содержатся в argv[] (всегда больше либо равен 1);
argv - в массиве строки представляют собой параметры из командной строки, введенные пользователем программы. По соглашению, argv [0] –это команда, которой была запущена программа, argv[1] – первый параметр из командной строки и так далее до argv[argc] – элемент, всегда равный NULL;
envp - это массив строк, которые представляют собой переменные окружения. Массив заканчивается значением NULL.
Для выполнения операций записи и чтения данных в существующем файле его следует открыть при помощи вызова open ().
int open (const char *pathname, int flags, [mode_t mode]);
int fopen (const char *pathname, int flags, [mode_t mode]);
Второй аргумент системного вызова open - flags - имеет целочисленный тип и определяет метод доступа. Параметр flagsпринимает одно из значений, заданных постоянными в заголовочном файле fcnt1.h. В файле определены три постоянных:
O_RDONLY – открыть файл только для чтения,
O_WRONLY – открыть файл только для записи,
O_RDWR – открыть файл для чтения и записи,
или “r”, “w”, “rw” для fopen().
Третий параметр mode устанавливает права доступа к файлуи является необязательным, он используется только вместе с флагом O_CREAT. Пример создания нового файла:
# include <sys / types.h>
# include <sys / stat.h>
# include <fcnt1.h>
int Fd1;
FILE *F1;
F1=fopen (“Myfile2.txt”, “w”, 644);
Fd1=open (“Myfile1.txt”, O_CREAT, 644);
Системные вызовы stat и fstat позволяют процессу определить значения свойств в существующем файле.
#include <sys/types.h>
#include <sys/stat.h>
int stat (const char *pathname, struct stat *buf);
int fstat (int filedes, struct stat *buf);
Пример: stat(“1.exe”, &st1);
Где pathname – полное имя файла, buf –структура типа stat. Эта структура после успешного вызова будет содержать связанную с файлом информацию.
Поля структуры stat включает следующие элементы:
struct stat {
dev_t st_dev; /* логическое устройство, где находится файл */
ino_t st_ino; /* номер индексного дескриптора */
mode_t st_mode; /* права доступа к файлу */
nlink_t st_nlink; /* количество жестких ссылок на файл */
uid_t st_uid; /* ID пользователя-владельца */
gid_t st_gid; /* ID группы-владельца */
dev_t st_rdev; /* тип устройства */
off_t st_size; /* общий размер в байтах */
unsigned long st_blksize; /* размер блока ввода-вывода */
unsigned long st_blocks; /* число блоков, занимаемых файлом */
time_t st_atime; /* время последнего доступа */
time_t st_mtime; /* время последней модификации */
time_t st_ctime; /* время последнего изменения */
};
Права доступа в Linux. Права доступа к файлам представлены в виде последовательности бит, где каждый бит означает разрешение на запись (w), чтение (r) или выполнение (x). Права доступа записываются для владельца-создателя файла (owner); группы, к которой принадлежит владелец–создатель файла (group); и всех остальных (other). Например, при выводе команды dir запись типа:
-rwx r-x r-w 1.exe
означает, что владелец файла 1.exe имеет права на чтение, запись и выполнение, группа имеет права только на чтение и выполнение, все остальные имеют права только на чтение. В восьмеричном виде получится значение 0754. В действительности манипулирует файлами не сам пользователь, а запущенный им процесс. Для просмотра прав доступа можно использовать функцию stat.
Для записи прав доступа служит функция chmod:
#include <sys/types.h>
#include <sys/stat.h>
int chmod(const char *pathname, mode_t mode);
Пример: chmod(“1.exe”, 0777);
Каталоги в ОС Linux –это особые файлы. Для открытия или закрытия каталогов существуют вызовы:
#include <dirent.h> DIR *opendir (const char *dirname); int closedir( DIR *dirptr); Для работы с каталогами существуют системные вызовы: int mkdir (const char *pathname, mode_t mode) – создание нового каталога, int rmdir(const char *pathname) – удаление каталога. Первый параметр – имя создаваемого каталога, второй – права доступа: retval=mkdir(“/home/s1/t12/alex”,0777); retval=rmdir(“/home/s1/t12/alex”);Заметим, что вызов rmdir(“/home/s1/t12/alex”) будет успешен, только если удаляемый каталог пуст, т.е. содержит записи “точка” (.) и “двойная точка” (..). Для чтения записей каталога существует вызов: struct dirent *readdir(DIR *dirptr);Структура dirent такова: struct dirent { long d_ino; off_t d_off; unsigned short d_reclen; char d_name [1]; };Поле d_ino - это число, которое уникально для каждого файла в файловой системе. Значением поля d_off служит смещение данного элемента в реальном каталоге. Поле d_name есть начало массива символов, задающего имя элемента каталога. Данное имя ограничено нулевым байтом и может содержать не более MAXNAMLEN символов. Тем самым описываемая структура имеет переменную длину, хранящуюся в поле d_reclen.Пример вызова: DIR *dp; struct dirent *d; d=readdir(dp);При первом вызове функция readdir в структуру dirent будет считана первая запись каталога. После прочтения всего каталога в результате последующих вызовов readdir будет возвращено значение NULL. Для возврата указателя в начало каталога на первую запись существует вызов: void rewindir(DIR *dirptr);Чтобы получить имя текущего рабочего каталога существует функция: char *getcwd(char *name, size_t size);Время в Linux отсчитывается в секундах, прошедшее с начала этой эпохи (00:00:00 UTC, 1 Января 1970 года). Для получения системного времени можно использовать следующие функции:
#include <sys/time.h>
time_t time (time_t *tt);
int gettimeofday(struct timeval *tv, struct timezone *tz);
struct timeval {
long tv_sec; /* секунды */
long tv_usec; /* микросекунды */
};