Автор оригинала: Doug Hellmann.
Цель:
Портативный доступ к специфическим функциям операционной системы.
Модуль os
предоставляет оболочку для модулей конкретной платформы, таких как posix
, nt
и mac
. API для функций, доступных на всех платформах, должен быть одинаковым, поэтому использование модуля os
обеспечивает некоторую мобильность. Однако не все функции доступны на каждой платформе. Многие из функций управления процессами, описанных в этом обзоре, недоступны для Windows.
Документация Python для модуля os
имеет подзаголовок «Разные интерфейсы операционной системы». Модуль состоит в основном из функций для создания и управления запущенными процессами или содержимым файловой системы (файлами и каталогами), а также из нескольких других функций.
Изучение содержимого файловой системы
Чтобы подготовить список содержимого каталога в файловой системе, используйте listdir ()
.
os_listdir.py
import os import sys print(sorted(os.listdir(sys.argv[1])))
Возвращаемое значение – это несортированный список всех названных членов данного каталога. Не делается различий между файлами, подкаталогами или символическими ссылками.
$ python3 os_listdir.py . ['index.rst', 'os_access.py', 'os_cwd_example.py', 'os_directories.py', 'os_environ_example.py', 'os_exec_example.py', 'os_fork_example.py', 'os_kill_example.py', 'os_listdir.py', 'os_listdir.py~', 'os_process_id_example.py', 'os_process_user_example.py', 'os_rename_replace.py', 'os_rename_replace.py~', 'os_scandir.py', 'os_scandir.py~', 'os_spawn_example.py', 'os_stat.py', 'os_stat_chmod.py', 'os_stat_chmod_example.txt', 'os_strerror.py', 'os_strerror.py~', 'os_symlinks.py', 'os_system_background.py', 'os_system_example.py', 'os_system_shell.py', 'os_wait_example.py', 'os_waitpid_example.py', 'os_walk.py']
Функция walk ()
рекурсивно просматривает каталог и для каждого подкаталога генерирует кортеж
, содержащий путь к каталогу, любые непосредственные подкаталоги этого пути и список имен любых файлов в этом каталоге.
os_walk.py
import os import sys # If we are not given a path to list, use /tmp if len(sys.argv) 1: root '/tmp' else: root sys.argv[1] for dir_name, sub_dirs, files in os.walk(root): print(dir_name) # Make the subdirectory names stand out with / sub_dirs [n + '/' for n in sub_dirs] # Mix the directory contents together contents sub_dirs + files contents.sort() # Show the contents for c in contents: print(' {}'.format(c)) print()
В этом примере показан рекурсивный список каталогов.
$ python3 os_walk.py ../zipimport ../zipimport __init__.py example_package/ index.rst zipimport_example.zip zipimport_find_module.py zipimport_get_code.py zipimport_get_data.py zipimport_get_data_nozip.py zipimport_get_data_zip.py zipimport_get_source.py zipimport_is_package.py zipimport_load_module.py zipimport_make_example.py ../zipimport/example_package README.txt __init__.py
Если требуется больше информации, чем имена файлов, вероятно, будет более эффективно использовать scandir ()
, чем listdir ()
, поскольку больше информации собирается в одной системе. звоните, когда каталог сканируется.
os_scandir.py
import os import sys for entry in os.scandir(sys.argv[1]): if entry.is_dir(): typ 'dir' elif entry.is_file(): typ 'file' elif entry.is_symlink(): typ 'link' else: typ 'unknown' print('{name} {typ}'.format( nameentry.name, typtyp, ))
scandir ()
возвращает последовательность экземпляров DirEntry
для элементов в каталоге. У объекта есть несколько атрибутов и методов для доступа к метаданным о файле.
$ python3 os_scandir.py . index.rst file os_access.py file os_cwd_example.py file os_directories.py file os_environ_example.py file os_exec_example.py file os_fork_example.py file os_kill_example.py file os_listdir.py file os_listdir.py~ file os_process_id_example.py file os_process_user_example.py file os_rename_replace.py file os_rename_replace.py~ file os_scandir.py file os_scandir.py~ file os_spawn_example.py file os_stat.py file os_stat_chmod.py file os_stat_chmod_example.txt file os_strerror.py file os_strerror.py~ file os_symlinks.py file os_system_background.py file os_system_example.py file os_system_shell.py file os_wait_example.py file os_waitpid_example.py file os_walk.py file
Управление разрешениями файловой системы
Подробную информацию о файле можно получить с помощью stat ()
или lstat ()
(для проверки статуса чего-то, что может быть символической ссылкой).
os_stat.py
import os import sys import time if len(sys.argv) 1: filename __file__ else: filename sys.argv[1] stat_info os.stat(filename) print('os.stat({}):'.format(filename)) print(' Size:', stat_info.st_size) print(' Permissions:', oct(stat_info.st_mode)) print(' Owner:', stat_info.st_uid) print(' Device:', stat_info.st_dev) print(' Created :', time.ctime(stat_info.st_ctime)) print(' Last modified:', time.ctime(stat_info.st_mtime)) print(' Last accessed:', time.ctime(stat_info.st_atime))
Результат будет зависеть от того, как был установлен пример кода. Попробуйте передать в os_stat.py
другие имена файлов в командной строке.
$ python3 os_stat.py os.stat(os_stat.py): Size: 593 Permissions: 0o100644 Owner: 527 Device: 16777218 Created : Sat Dec 17 12:09:51 2016 Last modified: Sat Dec 17 12:09:51 2016 Last accessed: Sat Dec 31 12:33:19 2016 $ python3 os_stat.py index.rst os.stat(index.rst): Size: 26878 Permissions: 0o100644 Owner: 527 Device: 16777218 Created : Sat Dec 31 12:33:10 2016 Last modified: Sat Dec 31 12:33:10 2016 Last accessed: Sat Dec 31 12:33:19 2016
В Unix-подобных системах права доступа к файлам можно изменить с помощью chmod ()
, передав режим как целое число. Значения режима могут быть созданы с использованием констант, определенных в модуле stat
. В этом примере переключается бит разрешения пользователя на выполнение:
os_stat_chmod.py
import os import stat filename 'os_stat_chmod_example.txt' if os.path.exists(filename): os.unlink(filename) with open(filename, 'wt') as f: f.write('contents') # Determine what permissions are already set using stat existing_permissions stat.S_IMODE(os.stat(filename).st_mode) if not os.access(filename, os.X_OK): print('Adding execute permission') new_permissions existing_permissions | stat.S_IXUSR else: print('Removing execute permission') # use xor to remove the user execute permission new_permissions existing_permissions ^ stat.S_IXUSR os.chmod(filename, new_permissions)
Сценарий предполагает, что у него есть разрешения, необходимые для изменения режима файла при запуске.
$ python3 os_stat_chmod.py Adding execute permission
Функцию access ()
можно использовать для проверки прав доступа процесса к файлу.
os_access.py
import os print('Testing:', __file__) print('Exists:', os.access(__file__, os.F_OK)) print('Readable:', os.access(__file__, os.R_OK)) print('Writable:', os.access(__file__, os.W_OK)) print('Executable:', os.access(__file__, os.X_OK))
Результаты будут отличаться в зависимости от того, как установлен пример кода, но результат будет примерно таким:
$ python3 os_access.py Testing: os_access.py Exists: True Readable: True Writable: True Executable: False
В документации библиотеки для access ()
есть два специальных предупреждения. Во-первых, нет особого смысла вызывать access ()
для проверки возможности открытия файла перед фактическим вызовом для него open ()
. Между двумя вызовами есть небольшой, но реальный промежуток времени, в течение которого права доступа к файлу могут измениться. Другое предупреждение относится в основном к сетевым файловым системам, которые расширяют семантику разрешений POSIX. Некоторые типы файловых систем могут отвечать на вызов POSIX о том, что у процесса есть разрешение на доступ к файлу, а затем сообщать об ошибке, когда попытка выполняется с помощью open ()
по какой-то причине, не проверенной с помощью вызова POSIX. В общем, лучше вызвать open ()
с требуемым режимом и поймать IOError
, возникшую в случае возникновения проблемы.
Создание и удаление каталогов
Есть несколько функций для работы с каталогами в файловой системе, включая создание, перечисление содержимого и его удаление.
os_directories.py
import os dir_name 'os_directories_example' print('Creating', dir_name) os.makedirs(dir_name) file_name os.path.join(dir_name, 'example.txt') print('Creating', file_name) with open(file_name, 'wt') as f: f.write('example file') print('Cleaning up') os.unlink(file_name) os.rmdir(dir_name)
Есть два набора функций для создания и удаления каталогов. При создании нового каталога с помощью mkdir ()
все родительские каталоги должны уже существовать. При удалении каталога с помощью rmdir ()
фактически удаляется только конечный каталог (последняя часть пути). Напротив, makedirs ()
и deletedirs ()
работают со всеми узлами в пути. makedirs ()
создаст любые несуществующие части пути, а deletedirs ()
удалит все родительские каталоги, пока они пусты.
$ python3 os_directories.py Creating os_directories_example Creating os_directories_example/example.txt Cleaning up
Работа с символическими ссылками
Для платформ и файловых систем, которые их поддерживают, есть функции для работы с символическими ссылками.
os_symlinks.py
import os link_name '/tmp/' + os.path.basename(__file__) print('Creating link {} -> {}'.format(link_name, __file__)) os.symlink(__file__, link_name) stat_info os.lstat(link_name) print('Permissions:', oct(stat_info.st_mode)) print('Points to:', os.readlink(link_name)) # Cleanup os.unlink(link_name)
Используйте symlink ()
для создания символической ссылки и readlink ()
для ее чтения, чтобы определить исходный файл, на который указывает ссылка. Функция lstat ()
похожа на stat ()
, но работает с символическими ссылками.
$ python3 os_symlinks.py Creating link /tmp/os_symlinks.py -> os_symlinks.py Permissions: 0o120755 Points to: os_symlinks.py
Безопасная замена существующего файла
Замена или переименование существующего файла не является идемпотентным и может подвергнуть приложения условиям гонки. Функции rename ()
и replace ()
реализуют безопасные алгоритмы для этих действий, используя атомарные операции в POSIX-совместимых системах, когда это возможно.
os_rename_replace.py
import glob import os with open('rename_start.txt', 'w') as f: f.write('starting as rename_start.txt') print('Starting:', glob.glob('rename*.txt')) os.rename('rename_start.txt', 'rename_finish.txt') print('After rename:', glob.glob('rename*.txt')) with open('rename_finish.txt', 'r') as f: print('Contents:', repr(f.read())) with open('rename_new_contents.txt', 'w') as f: f.write('ending with contents of rename_new_contents.txt') os.replace('rename_new_contents.txt', 'rename_finish.txt') with open('rename_finish.txt', 'r') as f: print('After replace:', repr(f.read())) for name in glob.glob('rename*.txt'): os.unlink(name)
Функции rename ()
и replace ()
большую часть времени работают в файловых системах. Переименование файла может завершиться неудачно, если он перемещается в новую файловую систему или место назначения уже существует.
$ python3 os_rename_replace.py Starting: ['rename_start.txt'] After rename: ['rename_finish.txt'] Contents: 'starting as rename_start.txt' After replace: 'ending with contents of rename_new_contents.txt'
Обнаружение и изменение владельца процесса
Следующий набор функций, предоставляемых os
, используется для определения и изменения идентификаторов владельцев процессов. Чаще всего они используются авторами демонов или специальных системных программ, которым необходимо изменить уровень разрешений, а не запускаться от имени root
. Этот раздел не пытается объяснить все сложные детали безопасности Unix, владельцев процессов и т. Д. См. Список ссылок в конце этого раздела для получения более подробной информации.
В следующем примере показаны реальные и эффективные сведения о пользователях и группах для процесса, а затем изменяются действующие значения. Это аналогично тому, что демон должен был бы сделать, когда он запускается от имени пользователя root во время загрузки системы, чтобы снизить уровень привилегий и запустить его от имени другого пользователя.
Примечание
Перед запуском примера измените значения TEST_GID
и TEST_UID
, чтобы они соответствовали реальному пользователю, определенному в системе.
os_process_user_example.py
import os TEST_GID 502 TEST_UID 502 def show_user_info(): print('User (actual/effective) : {} / {}'.format( os.getuid(), os.geteuid())) print('Group (actual/effective) : {} / {}'.format( os.getgid(), os.getegid())) print('Actual Groups :', os.getgroups()) print('BEFORE CHANGE:') show_user_info() print() try: os.setegid(TEST_GID) except OSError: print('ERROR: Could not change effective group. ' 'Rerun as root.') else: print('CHANGE GROUP:') show_user_info() print() try: os.seteuid(TEST_UID) except OSError: print('ERROR: Could not change effective user. ' 'Rerun as root.') else: print('CHANGE USER:') show_user_info() print()
При запуске от имени пользователя с идентификатором 502 и группой 502 в OS X создается следующий вывод:
$ python3 os_process_user_example.py BEFORE CHANGE: User (actual/effective) : 527 / 527 Group (actual/effective) : 501 / 501 Actual Groups : [501, 701, 402, 702, 500, 12, 61, 80, 98, 398, 399, 33, 100, 204, 395] ERROR: Could not change effective group. Rerun as root. ERROR: Could not change effective user. Rerun as root.
Значения не меняются, потому что, когда он не запущен как root, процесс не может изменить значение своего эффективного владельца. Любая попытка установить для эффективного идентификатора пользователя или группы значение, отличное от идентификатора текущего пользователя, вызывает OSError
. Другой сценарий – запустить тот же сценарий с использованием sudo
, чтобы он запускался с привилегиями root.
$ sudo python3 os_process_user_example.py BEFORE CHANGE: User (actual/effective) : 0 / 0 Group (actual/effective) : 0 / 0 Actual Groups : [0, 1, 2, 3, 4, 5, 8, 9, 12, 20, 29, 61, 80, 702, 33, 98, 100, 204, 395, 398, 399, 701] CHANGE GROUP: User (actual/effective) : 0 / 0 Group (actual/effective) : 0 / 502 Actual Groups : [0, 1, 2, 3, 4, 5, 8, 9, 12, 20, 29, 61, 80, 702, 33, 98, 100, 204, 395, 398, 399, 701] CHANGE USER: User (actual/effective) : 0 / 502 Group (actual/effective) : 0 / 502 Actual Groups : [0, 1, 2, 3, 4, 5, 8, 9, 12, 20, 29, 61, 80, 702, 33, 98, 100, 204, 395, 398, 399, 701]
В этом случае, поскольку он запускается от имени пользователя root, сценарий может изменить действующего пользователя и группу для процесса. После изменения действующего UID процесс ограничивается разрешениями этого пользователя. Поскольку пользователи без полномочий root не могут изменить свою действующую группу, программе необходимо изменить группу перед изменением пользователя.
Управление технологической средой
Другой особенностью операционной системы, доступной программе через модуль os
, является среда. Переменные, установленные в среде, отображаются в виде строк, которые можно прочитать с помощью os.environ
или getenv ()
. Переменные среды обычно используются для значений конфигурации, таких как пути поиска, расположение файлов и флаги отладки. В этом примере показано, как получить переменную среды и передать значение дочернему процессу.
os_environ_example.py
import os print('Initial value:', os.environ.get('TESTVAR', None)) print('Child process:') os.system('echo $TESTVAR') os.environ['TESTVAR'] 'THIS VALUE WAS CHANGED' print() print('Changed value:', os.environ['TESTVAR']) print('Child process:') os.system('echo $TESTVAR') del os.environ['TESTVAR'] print() print('Removed value:', os.environ.get('TESTVAR', None)) print('Child process:') os.system('echo $TESTVAR')
Объект os.environ
следует стандартному API сопоставления Python для получения и установки значений. Изменения в os.environ
экспортируются для дочерних процессов.
$ python3 -u os_environ_example.py Initial value: None Child process: Changed value: THIS VALUE WAS CHANGED Child process: THIS VALUE WAS CHANGED Removed value: None Child process:
Управление рабочим каталогом процесса
Операционные системы с иерархическими файловыми системами имеют понятие текущий рабочий каталог – каталог в файловой системе, который процесс использует в качестве начального местоположения при доступе к файлам по относительным путям. Текущий рабочий каталог можно получить с помощью getcwd ()
и изменить с помощью chdir ()
.
os_cwd_example.py
import os print('Starting:', os.getcwd()) print('Moving up one:', os.pardir) os.chdir(os.pardir) print('After move:', os.getcwd())
os.curdir
и os.pardir
используются для ссылки на текущий и родительский каталоги переносимым способом.
$ python3 os_cwd_example.py Starting: .../pymotw-3/source/os Moving up one: .. After move: .../pymotw-3/source
Запуск внешних команд
Предупреждение
Многие из этих функций для работы с процессами имеют ограниченную переносимость. Для более последовательного способа работы с процессами независимо от платформы см. Вместо этого модуль подпроцесса.
Самый простой способ запустить отдельную команду, не взаимодействуя с ней вообще, – это system ()
. Он принимает единственный строковый аргумент, который представляет собой командную строку, выполняемую подпроцессом, выполняющим оболочку.
os_system_example.py
import os # Simple command os.system('pwd')
Возвращаемое значение system ()
– это значение выхода оболочки, запускающей программу, упакованную в 16-битное число, причем старший байт – статус выхода, а младший байт – номер сигнала, который вызвал выполнение процесса. умереть или ноль.
$ python3 -u os_system_example.py .../pymotw-3/source/os
Поскольку команда передается непосредственно в оболочку для обработки, она может включать синтаксис оболочки, такой как глобализация или переменные среды.
os_system_shell.py
import os # Command with shell expansion os.system('echo $TMPDIR')
Переменная среды $ TMPDIR
в этой строке раскрывается, когда оболочка запускает командную строку.
$ python3 -u os_system_shell.py /var/folders/5q/8gk0wq888xlggz008k8dr7180000hg/T/
Если команда явно не запускается в фоновом режиме, вызов system ()
блокируется до завершения. Стандартный ввод, вывод и ошибка дочернего процесса привязаны к соответствующим потокам, принадлежащим вызывающему по умолчанию, но могут быть перенаправлены с помощью синтаксиса оболочки.
os_system_background.py
import os import time print('Calling...') os.system('date; (sleep 3; date) &') print('Sleeping...') time.sleep(5)
Однако это приводит к обману в оболочке, и есть более эффективные способы сделать то же самое.
$ python3 -u os_system_background.py Calling... Sat Dec 31 12:33:20 EST 2016 Sleeping... Sat Dec 31 12:33:23 EST 2016
Создание процессов с помощью os.fork ()
Функции POSIX fork ()
и exec ()
(доступные в Mac OS X, Linux и других вариантах Unix) доступны через os
модуль. О надежном использовании этих функций написаны целые книги, поэтому проверьте библиотеку или книжный магазин для получения более подробной информации, чем представлено здесь в этом введении.
Чтобы создать новый процесс как клон текущего процесса, используйте fork ()
:
os_fork_example.py
import os pid os.fork() if pid: print('Child process id:', pid) else: print('I am the child')
Результат будет зависеть от состояния системы каждый раз при запуске примера, но он будет выглядеть примерно так:
$ python3 -u os_fork_example.py Child process id: 29190 I am the child
После вилки два процесса выполняют один и тот же код. Чтобы программа могла определить, в какой из них она находится, ей необходимо проверить возвращаемое значение fork ()
. Если значение равно 0
, текущий процесс является дочерним. Если это не 0
, программа выполняется в родительском процессе, и возвращаемое значение – идентификатор процесса дочернего процесса.
os_kill_example.py
import os import signal import time def signal_usr1(signum, frame): "Callback invoked when a signal is received" pid os.getpid() print('Received USR1 in process {}'.format(pid)) print('Forking...') child_pid os.fork() if child_pid: print('PARENT: Pausing before sending signal...') time.sleep(1) print('PARENT: Signaling {}'.format(child_pid)) os.kill(child_pid, signal.SIGUSR1) else: print('CHILD: Setting up signal handler') signal.signal(signal.SIGUSR1, signal_usr1) print('CHILD: Pausing to wait for signal') time.sleep(5)
Родитель может отправлять сигналы дочернему процессу, используя kill ()
и модуль signal. Во-первых, определите обработчик сигнала, который будет вызываться при получении сигнала. Затем fork ()
и в родительской паузе на короткое время перед отправкой сигнала USR1
с помощью kill ()
. В этом примере используется короткая пауза, чтобы дать дочернему процессу время для настройки обработчика сигнала. Настоящему приложению не требуется (или не нужно) вызывать sleep ()
. В дочернем элементе настройте обработчик сигнала и отправляйтесь в режим сна на некоторое время, чтобы дать родителю время отправить сигнал.
$ python3 -u os_kill_example.py Forking... PARENT: Pausing before sending signal... CHILD: Setting up signal handler CHILD: Pausing to wait for signal PARENT: Signaling 29193 Received USR1 in process 29193
Простой способ справиться с раздельным поведением дочернего процесса – проверить возвращаемое значение fork ()
и ветвь. Более сложное поведение может потребовать большего разделения кода, чем простая ветвь. В других случаях может быть существующая программа, которую нужно обернуть. Для обеих этих ситуаций серию функций exec * ()
можно использовать для запуска другой программы.
os_exec_example.py
import os child_pid os.fork() if child_pid: os.waitpid(child_pid, 0) else: os.execlp('pwd', 'pwd', '-P')
Когда программа запускается с помощью exec ()
, код этой программы заменяет код существующего процесса.
$ python3 os_exec_example.py .../pymotw-3/source/os
Существует множество вариантов exec ()
, в зависимости от формы, в которой доступны аргументы, от того, следует ли копировать путь и среду родительского процесса в дочерний процесс и т. Д. Для всех вариантов первый аргумент – это путь или имя файла, а остальные аргументы управляют работой этой программы. Они либо передаются в качестве аргументов командной строки, либо переопределяют «среду» процесса (см. os.environ
и os.getenv
). Обратитесь к документации библиотеки для получения полной информации.
Ожидание дочерних процессов
Многие программы с интенсивными вычислениями используют несколько процессов для обхода ограничений потоковой передачи Python и глобальной блокировки интерпретатора. При запуске нескольких процессов для выполнения отдельных задач мастеру нужно будет дождаться завершения одного или нескольких из них, прежде чем запускать новые, чтобы избежать перегрузки сервера. Есть несколько способов сделать это с помощью wait ()
и связанных функций.
Если не имеет значения, какой дочерний процесс может завершиться первым, используйте wait ()
. Он возвращается, как только завершается любой дочерний процесс.
os_wait_example.py
import os import sys import time for i in range(2): print('PARENT {}: Forking {}'.format(os.getpid(), i)) worker_pid os.fork() if not worker_pid: print('WORKER {}: Starting'.format(i)) time.sleep(2 + i) print('WORKER {}: Finishing'.format(i)) sys.exit(i) for i in range(2): print('PARENT: Waiting for {}'.format(i)) done os.wait() print('PARENT: Child done:', done)
Возвращаемое значение из wait ()
– это кортеж, содержащий идентификатор процесса и статус выхода, объединенные в 16-битное значение. Младший байт – это номер сигнала, завершившего процесс, а старший байт – это код состояния, возвращаемый процессом при выходе.
$ python3 -u os_wait_example.py PARENT 29202: Forking 0 PARENT 29202: Forking 1 PARENT: Waiting for 0 WORKER 0: Starting WORKER 1: Starting WORKER 0: Finishing PARENT: Child done: (29203, 0) PARENT: Waiting for 1 WORKER 1: Finishing PARENT: Child done: (29204, 256)
Чтобы дождаться определенного процесса, используйте waitpid ()
.
os_waitpid_example.py
import os import sys import time workers [] for i in range(2): print('PARENT {}: Forking {}'.format(os.getpid(), i)) worker_pid os.fork() if not worker_pid: print('WORKER {}: Starting'.format(i)) time.sleep(2 + i) print('WORKER {}: Finishing'.format(i)) sys.exit(i) workers.append(worker_pid) for pid in workers: print('PARENT: Waiting for {}'.format(pid)) done os.waitpid(pid, 0) print('PARENT: Child done:', done)
Передайте идентификатор целевого процесса, и waitpid ()
блокируется, пока этот процесс не завершится.
$ python3 -u os_waitpid_example.py PARENT 29211: Forking 0 PARENT 29211: Forking 1 PARENT: Waiting for 29212 WORKER 0: Starting WORKER 1: Starting WORKER 0: Finishing PARENT: Child done: (29212, 0) PARENT: Waiting for 29213 WORKER 1: Finishing PARENT: Child done: (29213, 256)
wait3 ()
и wait4 ()
работают аналогичным образом, но возвращают более подробную информацию о дочернем процессе с идентификатором pid, статусом выхода и использованием ресурсов.
Создание новых процессов
Для удобства семейство функций spawn ()
обрабатывает fork ()
и exec ()
в одном операторе:
os_spawn_example.py
import os os.spawnlp(os.P_WAIT, 'pwd', 'pwd', '-P')
Первый аргумент – это режим, указывающий, следует ли ждать завершения процесса перед возвратом. Этот пример ждет. Используйте P_NOWAIT
, чтобы разрешить запуск другого процесса, но затем возобновить текущий процесс.
$ python3 os_spawn_example.py .../pymotw-3/source/os
Коды ошибок операционной системы
Коды ошибок, определенные операционной системой и управляемые в модуле errno
, могут быть преобразованы в строки сообщения с помощью strerror ()
.
os_strerror.py
import errno import os for num in [errno.ENOENT, errno.EINTR, errno.EBUSY]: name errno.errorcode[num] print('[{num:>2}] {name:<6}: {msg}'.format( namename, numnum, msgos.strerror(num)))
В этом примере показаны сообщения, связанные с некоторыми кодами ошибок, которые часто возникают.
$ python3 os_strerror.py [ 2] ENOENT: No such file or directory [ 4] EINTR : Interrupted system call [16] EBUSY : Resource busy
Смотрите также
- стандартная библиотека документации для ОС
- Заметки о переносе Python 2 на 3 для os
- signal – в разделе модуля
signal
более подробно рассматриваются методы обработки сигналов. - subprocess – модуль
subprocess
заменяетos.popen ()
. - многопроцессорность – модуль
multiprocessing
упрощает работу с дополнительными процессами. - tempfile – модуль
tempfile
для работы с временными файлами. - Работа с деревьями каталогов – модуль shutil также включает функции для работы с деревьями каталогов.
- Использование UNIX, часть 8. – Узнайте, как в UNIX решается многозадачность.
- Стандартные потоки – для более подробного обсуждения stdin, stdout и stderr.
- Подробнее о создании процесса Unix – объясняет жизненный цикл процесса Unix.
- Расширенное программирование в среде UNIX (R) У. Ричард Стивенс и Стивен А. Раго. Опубликовано Addison-Wesley Professional, 2005. ISBN-10: 0201433079 – В этой книге рассматривается работа с несколькими процессами, например обработка сигналов, закрытие дублированных файловых дескрипторов и т. Д.