Создание процессов и исполнение программ



Скачать 336,76 Kb.
страница3/7
Дата12.09.2017
Размер336,76 Kb.
1   2   3   4   5   6   7

Исполнение программы (продолжение)


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

Современные системы, в том числе Solaris, используют формат загружаемых файлов ELF (Executable and Linking Format). В заголовке файлов этого формата, помимо прочего, указана используемая система команд (x86, x64, SPARC, MIPS, ARM и др.). Разумеется, компьютер с процессором SPARC не может исполнять загрузочные модули x86/x64, а 32-битная версия ОС для x86 не может исполнять загрузочные модули x64.

Кроме бинарных модулей, современные Unix-системы могут исполнять текстовые файлы, если такие файлы начинаются с «магической последовательности» - строки вида #!pathname [arg], например, #!/bin/sh или #!/usr/bin/perl. Если файл начинается с такой строки, система интерпретирует pathname как имя программы-интерпретатора, запускает эту программу, передаёт ей аргументы [arg] (если они были указаны), затем имя файла и затем остальные аргументы exec(2). В результате, если файл с именем pathname действительно является программой-интерпретатором, он рассматривает запускаемый файл как программу на cоответствующем языке, например, командный файл shell или программу на языке Perl.

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

Любой файл, открытый перед вызовом exec(2), остается открытым, если при помощи fcntl(2) для его дескриптора не был установлен флаг закрыть-по-exec. Это обсуждалось в разделе, посвящённом системным вызовам ввода/вывода.

Для версий exec(2), не передающих среду исполнения в качестве параметра, в качестве новой среды используется массив указателей, на который указывает внешняя переменная environ.


      1. Запуск программ из shell


Командные интерпретаторы или командные оболочки Unix, такие, как sh(1), ksh(1), bash(1) и некоторые другие, часто объединяют под общим названием shell, так как их командные языки очень похожи. Командные языки shell описаны на соответствующих страницах руководства, а также во многих учебных пособиях для пользователей Unix. В действительности, командный язык shell представляет собой полнофункциональный (turing-complete) процедурный интерпретируемый язык программирования с переменными, разрушающим присваиванием, условными операторами, циклами и т. д. Полное изучение языка shell выходит за пределы нашего курса, но знакомство с этим языком полезно для выполнения многих упражнений и правильного понимания поведения системы.

Shell, как и другие программы на языке C, использует exec(2) для исполнения программ.

Shell читает командную строку с терминала или из командного файла, разделяет её на аргументы, затем создаёт дочерний процесс и в этом процессе вызывает exec(2) с соответствующими параметрами (основной процесс shell при этом ждёт завершения дочернего процесса). Первое слово командной строки — это имя программы, которую нужно исполнить, последующие аргументы — это значения argv[1] и последующих элементов вектора argv[]. Если имя программы содержит один или несколько символов /, оно интерпретируется как абсолютное или относительное путевое имя. Если же имя программы не содержит /, то исполняемый файл с таким именем ищется в списке каталогов, заданных в переменной среды PATH, как при использовании execvp(2). В действительности, некоторые командные оболочки (например, bash(1)) не используют execvp(2), а сами выполняют поиск файла по PATH и кэшируют результаты поиска во внутренних хэш-таблицах, что может ускорить исполнение длинных последовательностей команд.

Если один из аргументов команды содержит символы *, ? или [, shell интерпретирует такой аргумент как шаблон имени файла (точный формат шаблона описан на страницах руководства fnmatch(5) и sh(1)). Shell находит все файлы, соответствующие шаблону (если шаблон содержит также символы /, поиск может вестись в других каталогах; так, шаблон */* соответствует всем файлам во всех подкаталогах текущего каталога) и заменяет шаблон на список аргументов, каждый из которых соответствует одному из имён найденных файлов. Если файлов, соответствующих шаблону, не найдено, шаблон передаётся команде без изменений. Если вам нужно передать команде сам шаблон (например, команда find(1) или некоторые архиваторы ожидают шаблон имени файла, который следует найти), соответствующий аргумент необходимо экранировать одиночными или двойными кавычками, например find . -name '*.c' -print.

Важно отметить, что замена шаблонов осуществляется shell'ом, но не системными вызовами exec(2). Для замены шаблонов имён файлов в вашей программе следует использовать библиотечную функцию glob(3C).

Shell имеет встроенные переменные, значения которых представляют собой текстовые строки. Команда VAR=value присваивает переменной VAR значение value. Если переменная VAR не была определена, она будет создана. По умолчанию, встроенные переменные shell не передаются запускаемым программам. Чтобы переменная VAR стала частью среды запускаемых программ, необходимо выполнить команду export VAR. Некоторые оболочки, например, bash(1), допускают гибридный синтаксис команды export VAR=value, т. е. одновременное присваивание значения переменной и её экспорт.

Если вам нужно запустить команду с определённым значением переменной среды, не меняя значение соответствующей переменной shell, это можно сделать с использованием синтаксиса VAR=value cmd [arg] . Например, команда TZ=Asia/Tokyo date выдаст вам время и дату в Токио, не меняя значение переменной TZ.



      1. Поделитесь с Вашими друзьями:
1   2   3   4   5   6   7


База данных защищена авторским правом ©grazit.ru 2017
обратиться к администрации

    Главная страница