Ссылки на используемые функции/структуры
данных
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 --- универсальная среда программирования. Финансы и статистика. Москва 92. Джеймс Армстронг (мл.). Секреты UNIX. Диалектика. Киев 96. Сергей Дунаев. UNIX. System V. Release 4.2. Диалог МИФИ, Москва 95г. UNIX. X Window. Motif. ОСновы программирования (части I, II) АО Аналитик. Москва 94. |
С каждым Shell связан набор заданий, запущенных из данного Shell. Одна задача может работать в режиме foreground. Несколько задач могут работать в фоновом режиме (т.е. в режиме background). Для этого при запуске соответствующей команды после нее надо напечатать символ `&’:
startx&
При подобном запуске программы ее стандартный поток ввода отсоединяется от текущего терминала, но стандартный поток вывода все равно связан с текущим терминалом. При этом, если Shell, вызвавший данную программу умирает, то и данная программа также умирает. Добиться полного отсоединения программы от Shell можно с помощью команды nohup:
nohup prog&
При запуске последней программы стандартный поток вывода программы переадресовывается в файл nohup.out и программа не будет прервана даже при выходе пользователя из системы.
Задачи, связанные с запущенным Shell Bash, называются jobs. Список этих задач можно получить по команде jobs. Каждый job ассоциируется со своим номером. Эти номера можно получить по команде jobs.
При запуске задачи (процесса) в фоновом режиме с помощью команды с `&’ в ее конце сразу после запуска программы на экран выдается в квадратных скобках номер job нового процесса и ID нового процесса.
К любому процессу в системе можно обращаться по его номеру. Например, команда kill посылает сигнал процессу. Пример вызова:
kill –s 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&
В ОС 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
#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 классический вариант
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’ *