Лекция 6

 


Лекция 6.............................................................................................................................. 1

Работа в ОС UNIX............................................................................................................. 3

Интерпретаторы командной строки. Shell....................................................................... 3

Jobs.............................................................................................................................. 3

Отступление на тему языка С. Обработка сигналов (int sigaction(int signum,  const  struct  sigaction  *act,  sigaction *oldact); struct sigaction {  void (*sa_handler)(int);…).Таймер (int setitimer(int which, const struct itimerval *value, struct itimerval *OldValue);).......................................................... 4

Потоковые редакторы.................................................................................................... 6

grep. Поиск текста...................................................................................................... 6



 

Ссылки на используемые функции/структуры данных

 

int sigaction(int signum,  const  struct  sigaction  *act,  sigaction *oldact);

 

struct sigaction {

 void (*sa_handler)(int);

 void (*sa_sigaction)(int, siginfo_t *, void *);//if  sa_handler==SA_SIGINFO

 sigset_t sa_mask;// sigemptyset(&sa.sa_mask); for empty mask

 int sa_flags;  // SA_NOMASK for empty flags; SA_RESETHAND for reset

 void (*sa_restorer)(void);//not used

};

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

sighandler_t signal(int signum, sighandler_t handler);

typedef void (*sighandler_t)(int);

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

int setitimer(int which, const struct itimerval *value, struct itimerval *OldValue);

ITIMER_REAL (SIGALRM), ITIMER_VIRTUAL (SIGVTALRM),

ITIMER_PROF (SIGPROF)

struct itimerval {

               struct timeval it_interval; /* next value */

               struct timeval it_value;    /* current value */

           };

           struct timeval {

               long tv_sec;                /* seconds */

               long tv_usec;               /* microseconds */

           };

 


 

Работа в ОС UNIX.

 

Б.В.Кениган, Р.Пайк. UNIX --- универсальная среда программирования.

Финансы и статистика. Москва 92.

 

Джеймс Армстронг (мл.). Секреты UNIX. Диалектика. Киев 96.

 

Сергей Дунаев. UNIX. System V. Release 4.2. Диалог МИФИ, Москва 95г.

 

UNIX. X Window. Motif. ОСновы программирования (части I, II)

АО Аналитик. Москва 94.

 

 

 

Интерпретаторы командной строки. Shell

 

 

Jobs

С каждым Shell связан набор заданий, запущенных из данного Shell. Одна задача может работать в режиме foreground. Несколько задач могут работать в фоновом режиме (т.е. в режиме background). Для этого при запуске соответствующей команды после нее надо напечатать символ `&’:

startx&

 

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

nohup prog&

 

При запуске последней программы стандартный поток вывода программы переадресовывается в файл nohup.out и программа не будет прервана даже при выходе пользователя из системы.

Задачи, связанные с запущенным Shell Bash, называются jobs. Список этих задач можно получить по команде jobs. Каждый job ассоциируется со своим номером. Эти номера можно получить по команде jobs.

При запуске задачи (процесса) в фоновом режиме с помощью команды с `&в ее конце сразу после запуска программы на экран выдается в квадратных скобках номер job нового процесса  и ID нового процесса.

К любому процессу в системе можно обращаться по его номеру. Например, команда kill посылает сигнал процессу. Пример вызова:

kills 15 12777

здесь 15 – номер сигнала, 12777 ID процесса.

Для сигналов существуют стандартные буквенные обозначения. Например, сигнал SIGKILL  соответствует сигналу с номером 9. Этот сигнал приводит к прекращению работы процесса. Сигналу с номером 15 соответствует сигнал SIGTERM. Этот сигнал также приводит к прекращению работы процесса. Именно сигнал SIGTERM посылается процессу, если номер сигнала не указывается:

kill  12777

 

 Основным отличием этих сигналов является то, что реакцию на сигнал SIGTERM можно переопределить (см. ниже), а реакцию на сигнал SIGKILL  переопределить нельзя.

Задачу, выполняющуюся в режиме foreground можно приостановить командой ^Z (эквивалентно посылке сигнала SIGSTOP). Продолжить ее выполнение можно или в фоновом режиме командой

fg %n

где n – номер данного job, или в режиме background командой

bg %n

 

Те же самые команды можно более коротко вызвать:

%n

%n&

 

Отступление на тему языка С. Обработка сигналов (int sigaction(int signum,  const  struct  sigaction  *act,  sigaction *oldact); struct sigaction {  void (*sa_handler)(int);…).Таймер (int setitimer(int which, const struct itimerval *value, struct itimerval *OldValue);)

В ОС UNIX процессам можно передавать некоторые сигналы. Сигналы задаются номером сигнала. Например, нажатие комбинации клавиш ^Z посылает сигнал SIGSTOP. По умолчанию реакция на большинство сигналов – остановка процесса. Это действие можно переопределить. Для этого используется функция

int sigaction(int signum,  const  struct  sigaction  *act,  sigaction *oldact);

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

struct sigaction {

 void (*sa_handler)(int);

 void (*sa_sigaction)(int, siginfo_t *, void *);//if  sa_handler==SA_SIGINFO

 sigset_t sa_mask;

 int sa_flags;

 void (*sa_restorer)(void);//not used

};

 

В переменную sa_handler следует положить указатель на функцию, которая будет обрабатывать сигнал (вместо этого, можно инициализировать функцию sa_sigaction, имеющую другие параметры; часто данная структура определяется как union, в котором обе переменные располагаются по одному адресу). В Linux если  sa_handler задан, то sa_sigaction не используется. Если  sa_handler равен SA_SIGINFO, то используется функция, заданная параметром sa_sigaction.

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

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

В следующем примере переопределяется реакция на сигнал SIGTERM, после чего в ответ на команду kill %1,  программа печатает на экране Signal 15”.

 

 

 

 

#include <stdio.h>

#include <signal.h>

#include <unistd.h>

void OnSignal(int num){ printf("Signal %d\n",num); }

        

int main()

{struct sigaction sa;

   sa.sa_handler=OnSignal;

   sa.sa_flags=SA_NOMASK;

   sigemptyset(&sa.sa_mask);

   sigaction(15, &sa,NULL);

   while(1)sleep(1);

   return 0;

}

 

В GNU-C существует более простая возможность изменения реакции на сигнал. Для этого используется функция

sighandler_t signal(int signum, sighandler_t handler);

где тип sighandler задается следующим образом

typedef void (*sighandler_t)(int);

 

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

Существует возможность посылки сигналов по таймеру. Для этих целей используется функция

int setitimer(int which, const struct itimerval *value, struct itimerval *OldValue);

struct itimerval {

               struct timeval it_interval; /* next value */

               struct timeval it_value;    /* current value */

           };

           struct timeval {

               long tv_sec;                /* seconds */

               long tv_usec;               /* microseconds */

           };

 

Всего существует три таймера, задаваемых параметром which:

ITIMER_REAL              для отсчета времени по реальному времени; посылает сигнал SIGALRM

ITIMER_VIRTUAL        для отсчета по чистому времени работы программы; посылает сигнал SIGVTALRM

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

 

В параметр  value->it_value следует положить значение времени, по истечении которого будет послан сигнал. Нулевое значение данной величины отключает таймер. При истечении времени посылается сигнал и значение value->it_value устанавливается равным value->it_interval.

Значение OldValue может быть нулевым.

Получить значения текущих таймеров можно с помощью функции

int getitimer(int which, struct itimerval *value);

 

Потоковые редакторы

 

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

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

 

grep. Поиск текста

Используется для поиска текста в файлах. Существует три основных разновидности программы:

grep       классический вариант

egrep      для работы с большими файлами и сложными выражениями; использует расширенные выражения

fgrep      для поиска нескольких строк (отдельные шаблоны поиска разделяются переходом на следующую строку)

 

Полезные ключи

-i                        ignore case

-c           выводит имена файлов, в которых осуществлялся поиск, и количество найденных строк

-l                        выводит только имена файлов, в которых найдена искомая строки

 

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

 

Шаблоны:

Повторители:

+            1 или более раз

*             любое к-во раз

?             0 или 1 раз

{m,n}     от m до n  раз

{,n}        до n  раз

{m,}       не менее m раз

{n}         n  раз

 

Спец. символы:

^             начало строки

$             конец строки

|              или

 

Именованные выражения

\(expr\)               вместо expr можно подставить любое регулярное выражение. После этого на данное выражение получает имя, равное его порядковому номеру (первое выражение – имя \1, второе – имя \2 и т.д.).  Например, далее мы ищем все слова- перевертыши длиной не менее 2 и не более 5 (слова, написание которых не зависит от направления записи):

grep ’\(.\)\1\|\(.\).\1\|\(.\)\(.\)\2\1\|\(.\)\(.\).\2\1’ *