21693 pts/8 00:00:00 bash
21694 pts/8 00:00:00 ps
В данном случае мы видим два процесса. Первый из них. bash
, — это интерпретатор команд, запущенный на данном терминале. Второй — выполняющийся экземпляр самой команды ps
. В самом левом столбце, PID, отображаются идентификаторы процессов.
Более полный список можно получить с помощью следующей команды:
% ps -е -о pid,ppid,command
Опция -е
заставляет команду ps отображать все процессы, выполняющиеся в системе. Опция -о pid,ppid,command
сообщает о том, какая информация о процессе нас интересует. В данном случае это идентификатор самого процесса, идентификатор его родительского процесса и команда, посредством которой был запущен процесс.
ps
В опции -o
через запятую указываются столбцы которые должны быть включены в вывод команды ps
. Например, команда ps -о pid,user,start_time,command
отображает идентификатор процесса, имя его владельца, время запуска а также команду, соответствующую процессу. Полный список опций и столбцов можно узнать на man
-странице команды ps
. Имеются три предопределенных формата вывода: -f
(полный листинг), -l
(длинный листинг) и -j
(вывод заданий)
Ниже приведено несколько первых и последних строк, выдаваемых этой командой в нашей системе:
% ps -e -о pid,ppid,command
PID PPID COMMAND
1 0 init [5]
2 1 [kflushd]
3 1 [kupdate]
...
21725 21693 xterm
21727 21725 bash
21728 21727 ps -e -o pid,ppid,command
Заметьте: родительский идентификатор команды ps
, 21727, соответствует интерпретатору bash
, из которого была вызвана команда. В свою очередь, родительский идентификатор интерпретатора, 21725, принадлежит программе xterm
— эмулятору терминала, в котором выполняется интерпретатор.
3.1.3. Уничтожение процесса
Для уничтожения процесса предназначена команда kill
. Ей достаточно указать идентификатор требуемого процесса.
Команда kill
посылает процессу сигнал SIGTERM
, являющийся запросом на завершение.[10] По умолчанию, если в программе отсутствует обработчик данного сигнала, процесс просто завершает свою работу. О сигналах речь пойдет в разделе 3.3, "Сигналы".
3.2. Создание процессов
Существуют два способа создания процессов. Первый из них относительно прост, но применяется редко, поскольку неэффективен и связан со значительным риском для безопасности системы. Второй способ сложнее, но избавлен от недостатков первого.
3.2.1. Функция system()
Функция system()
определена в стандартной библиотеке языка С и позволяет вызывать из программы системную команду, как если бы она была набрана в командной строке. По сути, эта функция запускает стандартный интерпретатор Bourne shell (/bin/sh
) и передает ему команду на выполнение. Например, программа, представленная в листинге 3.2, вызывает команду ls -l /
, отображающую содержимое корневого каталога.
system()
#include
int main() {
int return_value;
return_value = system("ls -l /");
return return_value;
}
Функция system()
возвращает код завершения указанной команды. Если интерпретатор не может быть запущен, возвращается значение 127, а в случае возникновения других ошибок — -1.
Поскольку функция system()
запускает интерпретатор команд, она подвержена всем тем ограничениям безопасности, что и системный интерпретатор. Рассчитывать на наличие какой-то конкретной версии Bourne shell не приходится. В большинстве UNIX-систем программа /bin/sh
представляет собой символическую ссылку на другой интерпретатор. В Linux — это bash
(Bourne-Again SHell), причем в разных дистрибутивах присутствуют разные его версии. Вызов из функции system()
программы с привилегиями пользователя root
также может иметь неодинаковые последствия в разных системах. Таким образом, лучше создавать процессы с помощью функций fork()
и exec()
.
3.2.2. Функции fork() и exec()