zoukankan      html  css  js  c++  java
  • os

    os模块提供便捷的与操作系统交互的方法。

    1, os.name 

     导入的操作系统相关模块的名称,现在已经注册的有:'posix',‘nt’,'java'

    2, os.uname() 

    posix.uname_result(sysname='Linux', nodename='gate02', release='3.10.0-957.5.1.el7.x86_64', version='#1 SMP Fri Feb 1 14:54:57 UTC 2019', machine='x86_64')

    用于显示系统相关信息,与sys.platform相似

    3, os.ctermid() 

    仅unix可用,返回进程控制端对应的文件名

    '/dev/tty'

    4, os.environ  os.environb 

    显示所有环境变量,也可以指定

    >>> os.environ['VIVADO_HOME']
    '/home/eda/xilinx/Vivado/2017.4'

    5, os.chdir(path) 切换路径

    6, os.getcwd() 查看当前路径

    7, os.fchdir(fd) 通过文件描述符fd切换路径

    8, os.getenv(key,defualt=none)  得到环境变量值

    >>> os.getenv('VCS_HOME',)
    '/home/eda/synopsys/vcs/M-2017.03-SP2-10'

    9, os.get_exec_path(env=None)  得到可执行文件的路径

    10, os.getegid()  return the effective group id of the current process.--set id--only unix

    11, os.geteuid()  return the effective user id of the current process. --only unix

    12, os.getgid()  return the real group id of the current process. --only unix

    13, os.getgrouplist(user,group)  Return list of group ids that user belongs to. --only unix

    >>> os.getgrouplist('yuzhimin',1)
    [1, 9002, 9001, 9010, 9003]
    >>> os.getgrouplist('yuzhimin',9002)
    [9002, 9001, 9010, 9003]

    与linux下: id user 功能类似

    14, os.getgroups()  Return list of supplemental group ids associated with the current process. --only unix

    >>> os.getgroups()
    [9001, 9002, 9003, 9010, 9016, 100251]

    与linux下groups功能类似

    15, os.getlogin()  Return the name of the user logged in on the controlling terminal of the process

    16, os.getpgid(pid)  Return the process group id of the process with process id pid. If pid is 0, the process group id of the current process is returned --only unix

    17, os.getpgrp()  Return the id of the current process group.--only unix

    18, os.getpid()  Return the current process id

    19, os.getppid()  Return the parent’s process id

    20, os.listdir(path)  Return a list containing the names of the entries in the directory given by path

    21, os.mkdir(path,mode=0o777,*,dir_fd=None)  Create a directory named path with numeric mode mode

    22, os.remove(path,*,dir_fd=None)  

    23, os.removedirs(path)  

       1 r"""OS routines for NT or Posix depending on what system we're on.
       2 
       3 
       4 
       5 This exports:
       6 
       7   - all functions from posix or nt, e.g. unlink, stat, etc.
       8 
       9   - os.path is either posixpath or ntpath
      10 
      11   - os.name is either 'posix' or 'nt'
      12 
      13   - os.curdir is a string representing the current directory (always '.')
      14 
      15   - os.pardir is a string representing the parent directory (always '..')
      16 
      17   - os.sep is the (or a most common) pathname separator ('/' or '\')
      18 
      19   - os.extsep is the extension separator (always '.')
      20 
      21   - os.altsep is the alternate pathname separator (None or '/')
      22 
      23   - os.pathsep is the component separator used in $PATH etc
      24 
      25   - os.linesep is the line separator in text files ('
    ' or '
    ' or '
    ')
      26 
      27   - os.defpath is the default search path for executables
      28 
      29   - os.devnull is the file path of the null device ('/dev/null', etc.)
      30 
      31 
      32 
      33 Programs that import and use 'os' stand a better chance of being
      34 
      35 portable between different platforms.  Of course, they must then
      36 
      37 only use functions that are defined by all platforms (e.g., unlink
      38 
      39 and opendir), and leave all pathname manipulation to os.path
      40 
      41 (e.g., split and join).
      42 
      43 """
      44 
      45 
      46 
      47 #'
      48 
      49 import abc
      50 
      51 import sys
      52 
      53 import stat as st
      54 
      55 
      56 
      57 from _collections_abc import _check_methods
      58 
      59 
      60 
      61 _names = sys.builtin_module_names
      62 
      63 
      64 
      65 # Note:  more names are added to __all__ later.
      66 
      67 __all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
      68 
      69            "defpath", "name", "path", "devnull", "SEEK_SET", "SEEK_CUR",
      70 
      71            "SEEK_END", "fsencode", "fsdecode", "get_exec_path", "fdopen",
      72 
      73            "popen", "extsep"]
      74 
      75 
      76 
      77 def _exists(name):
      78 
      79     return name in globals()
      80 
      81 
      82 
      83 def _get_exports_list(module):
      84 
      85     try:
      86 
      87         return list(module.__all__)
      88 
      89     except AttributeError:
      90 
      91         return [n for n in dir(module) if n[0] != '_']
      92 
      93 
      94 
      95 # Any new dependencies of the os module and/or changes in path separator
      96 
      97 # requires updating importlib as well.
      98 
      99 if 'posix' in _names:
     100 
     101     name = 'posix'
     102 
     103     linesep = '
    '
     104 
     105     from posix import *
     106 
     107     try:
     108 
     109         from posix import _exit
     110 
     111         __all__.append('_exit')
     112 
     113     except ImportError:
     114 
     115         pass
     116 
     117     import posixpath as path
     118 
     119 
     120 
     121     try:
     122 
     123         from posix import _have_functions
     124 
     125     except ImportError:
     126 
     127         pass
     128 
     129 
     130 
     131     import posix
     132 
     133     __all__.extend(_get_exports_list(posix))
     134 
     135     del posix
     136 
     137 
     138 
     139 elif 'nt' in _names:
     140 
     141     name = 'nt'
     142 
     143     linesep = '
    '
     144 
     145     from nt import *
     146 
     147     try:
     148 
     149         from nt import _exit
     150 
     151         __all__.append('_exit')
     152 
     153     except ImportError:
     154 
     155         pass
     156 
     157     import ntpath as path
     158 
     159 
     160 
     161     import nt
     162 
     163     __all__.extend(_get_exports_list(nt))
     164 
     165     del nt
     166 
     167 
     168 
     169     try:
     170 
     171         from nt import _have_functions
     172 
     173     except ImportError:
     174 
     175         pass
     176 
     177 
     178 
     179 else:
     180 
     181     raise ImportError('no os specific module found')
     182 
     183 
     184 
     185 sys.modules['os.path'] = path
     186 
     187 from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
     188 
     189     devnull)
     190 
     191 
     192 
     193 del _names
     194 
     195 
     196 
     197 
     198 
     199 if _exists("_have_functions"):
     200 
     201     _globals = globals()
     202 
     203     def _add(str, fn):
     204 
     205         if (fn in _globals) and (str in _have_functions):
     206 
     207             _set.add(_globals[fn])
     208 
     209 
     210 
     211     _set = set()
     212 
     213     _add("HAVE_FACCESSAT",  "access")
     214 
     215     _add("HAVE_FCHMODAT",   "chmod")
     216 
     217     _add("HAVE_FCHOWNAT",   "chown")
     218 
     219     _add("HAVE_FSTATAT",    "stat")
     220 
     221     _add("HAVE_FUTIMESAT",  "utime")
     222 
     223     _add("HAVE_LINKAT",     "link")
     224 
     225     _add("HAVE_MKDIRAT",    "mkdir")
     226 
     227     _add("HAVE_MKFIFOAT",   "mkfifo")
     228 
     229     _add("HAVE_MKNODAT",    "mknod")
     230 
     231     _add("HAVE_OPENAT",     "open")
     232 
     233     _add("HAVE_READLINKAT", "readlink")
     234 
     235     _add("HAVE_RENAMEAT",   "rename")
     236 
     237     _add("HAVE_SYMLINKAT",  "symlink")
     238 
     239     _add("HAVE_UNLINKAT",   "unlink")
     240 
     241     _add("HAVE_UNLINKAT",   "rmdir")
     242 
     243     _add("HAVE_UTIMENSAT",  "utime")
     244 
     245     supports_dir_fd = _set
     246 
     247 
     248 
     249     _set = set()
     250 
     251     _add("HAVE_FACCESSAT",  "access")
     252 
     253     supports_effective_ids = _set
     254 
     255 
     256 
     257     _set = set()
     258 
     259     _add("HAVE_FCHDIR",     "chdir")
     260 
     261     _add("HAVE_FCHMOD",     "chmod")
     262 
     263     _add("HAVE_FCHOWN",     "chown")
     264 
     265     _add("HAVE_FDOPENDIR",  "listdir")
     266 
     267     _add("HAVE_FDOPENDIR",  "scandir")
     268 
     269     _add("HAVE_FEXECVE",    "execve")
     270 
     271     _set.add(stat) # fstat always works
     272 
     273     _add("HAVE_FTRUNCATE",  "truncate")
     274 
     275     _add("HAVE_FUTIMENS",   "utime")
     276 
     277     _add("HAVE_FUTIMES",    "utime")
     278 
     279     _add("HAVE_FPATHCONF",  "pathconf")
     280 
     281     if _exists("statvfs") and _exists("fstatvfs"): # mac os x10.3
     282 
     283         _add("HAVE_FSTATVFS", "statvfs")
     284 
     285     supports_fd = _set
     286 
     287 
     288 
     289     _set = set()
     290 
     291     _add("HAVE_FACCESSAT",  "access")
     292 
     293     # Some platforms don't support lchmod().  Often the function exists
     294 
     295     # anyway, as a stub that always returns ENOSUP or perhaps EOPNOTSUPP.
     296 
     297     # (No, I don't know why that's a good design.)  ./configure will detect
     298 
     299     # this and reject it--so HAVE_LCHMOD still won't be defined on such
     300 
     301     # platforms.  This is Very Helpful.
     302 
     303     #
     304 
     305     # However, sometimes platforms without a working lchmod() *do* have
     306 
     307     # fchmodat().  (Examples: Linux kernel 3.2 with glibc 2.15,
     308 
     309     # OpenIndiana 3.x.)  And fchmodat() has a flag that theoretically makes
     310 
     311     # it behave like lchmod().  So in theory it would be a suitable
     312 
     313     # replacement for lchmod().  But when lchmod() doesn't work, fchmodat()'s
     314 
     315     # flag doesn't work *either*.  Sadly ./configure isn't sophisticated
     316 
     317     # enough to detect this condition--it only determines whether or not
     318 
     319     # fchmodat() minimally works.
     320 
     321     #
     322 
     323     # Therefore we simply ignore fchmodat() when deciding whether or not
     324 
     325     # os.chmod supports follow_symlinks.  Just checking lchmod() is
     326 
     327     # sufficient.  After all--if you have a working fchmodat(), your
     328 
     329     # lchmod() almost certainly works too.
     330 
     331     #
     332 
     333     # _add("HAVE_FCHMODAT",   "chmod")
     334 
     335     _add("HAVE_FCHOWNAT",   "chown")
     336 
     337     _add("HAVE_FSTATAT",    "stat")
     338 
     339     _add("HAVE_LCHFLAGS",   "chflags")
     340 
     341     _add("HAVE_LCHMOD",     "chmod")
     342 
     343     if _exists("lchown"): # mac os x10.3
     344 
     345         _add("HAVE_LCHOWN", "chown")
     346 
     347     _add("HAVE_LINKAT",     "link")
     348 
     349     _add("HAVE_LUTIMES",    "utime")
     350 
     351     _add("HAVE_LSTAT",      "stat")
     352 
     353     _add("HAVE_FSTATAT",    "stat")
     354 
     355     _add("HAVE_UTIMENSAT",  "utime")
     356 
     357     _add("MS_WINDOWS",      "stat")
     358 
     359     supports_follow_symlinks = _set
     360 
     361 
     362 
     363     del _set
     364 
     365     del _have_functions
     366 
     367     del _globals
     368 
     369     del _add
     370 
     371 
     372 
     373 
     374 
     375 # Python uses fixed values for the SEEK_ constants; they are mapped
     376 
     377 # to native constants if necessary in posixmodule.c
     378 
     379 # Other possible SEEK values are directly imported from posixmodule.c
     380 
     381 SEEK_SET = 0
     382 
     383 SEEK_CUR = 1
     384 
     385 SEEK_END = 2
     386 
     387 
     388 
     389 # Super directory utilities.
     390 
     391 # (Inspired by Eric Raymond; the doc strings are mostly his)
     392 
     393 
     394 
     395 def makedirs(name, mode=0o777, exist_ok=False):
     396 
     397     """makedirs(name [, mode=0o777][, exist_ok=False])
     398 
     399 
     400 
     401     Super-mkdir; create a leaf directory and all intermediate ones.  Works like
     402 
     403     mkdir, except that any intermediate path segment (not just the rightmost)
     404 
     405     will be created if it does not exist. If the target directory already
     406 
     407     exists, raise an OSError if exist_ok is False. Otherwise no exception is
     408 
     409     raised.  This is recursive.
     410 
     411 
     412 
     413     """
     414 
     415     head, tail = path.split(name)
     416 
     417     if not tail:
     418 
     419         head, tail = path.split(head)
     420 
     421     if head and tail and not path.exists(head):
     422 
     423         try:
     424 
     425             makedirs(head, exist_ok=exist_ok)
     426 
     427         except FileExistsError:
     428 
     429             # Defeats race condition when another thread created the path
     430 
     431             pass
     432 
     433         cdir = curdir
     434 
     435         if isinstance(tail, bytes):
     436 
     437             cdir = bytes(curdir, 'ASCII')
     438 
     439         if tail == cdir:           # xxx/newdir/. exists if xxx/newdir exists
     440 
     441             return
     442 
     443     try:
     444 
     445         mkdir(name, mode)
     446 
     447     except OSError:
     448 
     449         # Cannot rely on checking for EEXIST, since the operating system
     450 
     451         # could give priority to other errors like EACCES or EROFS
     452 
     453         if not exist_ok or not path.isdir(name):
     454 
     455             raise
     456 
     457 
     458 
     459 def removedirs(name):
     460 
     461     """removedirs(name)
     462 
     463 
     464 
     465     Super-rmdir; remove a leaf directory and all empty intermediate
     466 
     467     ones.  Works like rmdir except that, if the leaf directory is
     468 
     469     successfully removed, directories corresponding to rightmost path
     470 
     471     segments will be pruned away until either the whole path is
     472 
     473     consumed or an error occurs.  Errors during this latter phase are
     474 
     475     ignored -- they generally mean that a directory was not empty.
     476 
     477 
     478 
     479     """
     480 
     481     rmdir(name)
     482 
     483     head, tail = path.split(name)
     484 
     485     if not tail:
     486 
     487         head, tail = path.split(head)
     488 
     489     while head and tail:
     490 
     491         try:
     492 
     493             rmdir(head)
     494 
     495         except OSError:
     496 
     497             break
     498 
     499         head, tail = path.split(head)
     500 
     501 
     502 
     503 def renames(old, new):
     504 
     505     """renames(old, new)
     506 
     507 
     508 
     509     Super-rename; create directories as necessary and delete any left
     510 
     511     empty.  Works like rename, except creation of any intermediate
     512 
     513     directories needed to make the new pathname good is attempted
     514 
     515     first.  After the rename, directories corresponding to rightmost
     516 
     517     path segments of the old name will be pruned until either the
     518 
     519     whole path is consumed or a nonempty directory is found.
     520 
     521 
     522 
     523     Note: this function can fail with the new directory structure made
     524 
     525     if you lack permissions needed to unlink the leaf directory or
     526 
     527     file.
     528 
     529 
     530 
     531     """
     532 
     533     head, tail = path.split(new)
     534 
     535     if head and tail and not path.exists(head):
     536 
     537         makedirs(head)
     538 
     539     rename(old, new)
     540 
     541     head, tail = path.split(old)
     542 
     543     if head and tail:
     544 
     545         try:
     546 
     547             removedirs(head)
     548 
     549         except OSError:
     550 
     551             pass
     552 
     553 
     554 
     555 __all__.extend(["makedirs", "removedirs", "renames"])
     556 
     557 
     558 
     559 def walk(top, topdown=True, onerror=None, followlinks=False):
     560 
     561     """Directory tree generator.
     562 
     563 
     564 
     565     For each directory in the directory tree rooted at top (including top
     566 
     567     itself, but excluding '.' and '..'), yields a 3-tuple
     568 
     569 
     570 
     571         dirpath, dirnames, filenames
     572 
     573 
     574 
     575     dirpath is a string, the path to the directory.  dirnames is a list of
     576 
     577     the names of the subdirectories in dirpath (excluding '.' and '..').
     578 
     579     filenames is a list of the names of the non-directory files in dirpath.
     580 
     581     Note that the names in the lists are just names, with no path components.
     582 
     583     To get a full path (which begins with top) to a file or directory in
     584 
     585     dirpath, do os.path.join(dirpath, name).
     586 
     587 
     588 
     589     If optional arg 'topdown' is true or not specified, the triple for a
     590 
     591     directory is generated before the triples for any of its subdirectories
     592 
     593     (directories are generated top down).  If topdown is false, the triple
     594 
     595     for a directory is generated after the triples for all of its
     596 
     597     subdirectories (directories are generated bottom up).
     598 
     599 
     600 
     601     When topdown is true, the caller can modify the dirnames list in-place
     602 
     603     (e.g., via del or slice assignment), and walk will only recurse into the
     604 
     605     subdirectories whose names remain in dirnames; this can be used to prune the
     606 
     607     search, or to impose a specific order of visiting.  Modifying dirnames when
     608 
     609     topdown is false has no effect on the behavior of os.walk(), since the
     610 
     611     directories in dirnames have already been generated by the time dirnames
     612 
     613     itself is generated. No matter the value of topdown, the list of
     614 
     615     subdirectories is retrieved before the tuples for the directory and its
     616 
     617     subdirectories are generated.
     618 
     619 
     620 
     621     By default errors from the os.scandir() call are ignored.  If
     622 
     623     optional arg 'onerror' is specified, it should be a function; it
     624 
     625     will be called with one argument, an OSError instance.  It can
     626 
     627     report the error to continue with the walk, or raise the exception
     628 
     629     to abort the walk.  Note that the filename is available as the
     630 
     631     filename attribute of the exception object.
     632 
     633 
     634 
     635     By default, os.walk does not follow symbolic links to subdirectories on
     636 
     637     systems that support them.  In order to get this functionality, set the
     638 
     639     optional argument 'followlinks' to true.
     640 
     641 
     642 
     643     Caution:  if you pass a relative pathname for top, don't change the
     644 
     645     current working directory between resumptions of walk.  walk never
     646 
     647     changes the current directory, and assumes that the client doesn't
     648 
     649     either.
     650 
     651 
     652 
     653     Example:
     654 
     655 
     656 
     657     import os
     658 
     659     from os.path import join, getsize
     660 
     661     for root, dirs, files in os.walk('python/Lib/email'):
     662 
     663         print(root, "consumes", end="")
     664 
     665         print(sum([getsize(join(root, name)) for name in files]), end="")
     666 
     667         print("bytes in", len(files), "non-directory files")
     668 
     669         if 'CVS' in dirs:
     670 
     671             dirs.remove('CVS')  # don't visit CVS directories
     672 
     673 
     674 
     675     """
     676 
     677     top = fspath(top)
     678 
     679     dirs = []
     680 
     681     nondirs = []
     682 
     683     walk_dirs = []
     684 
     685 
     686 
     687     # We may not have read permission for top, in which case we can't
     688 
     689     # get a list of the files the directory contains.  os.walk
     690 
     691     # always suppressed the exception then, rather than blow up for a
     692 
     693     # minor reason when (say) a thousand readable directories are still
     694 
     695     # left to visit.  That logic is copied here.
     696 
     697     try:
     698 
     699         # Note that scandir is global in this module due
     700 
     701         # to earlier import-*.
     702 
     703         scandir_it = scandir(top)
     704 
     705     except OSError as error:
     706 
     707         if onerror is not None:
     708 
     709             onerror(error)
     710 
     711         return
     712 
     713 
     714 
     715     with scandir_it:
     716 
     717         while True:
     718 
     719             try:
     720 
     721                 try:
     722 
     723                     entry = next(scandir_it)
     724 
     725                 except StopIteration:
     726 
     727                     break
     728 
     729             except OSError as error:
     730 
     731                 if onerror is not None:
     732 
     733                     onerror(error)
     734 
     735                 return
     736 
     737 
     738 
     739             try:
     740 
     741                 is_dir = entry.is_dir()
     742 
     743             except OSError:
     744 
     745                 # If is_dir() raises an OSError, consider that the entry is not
     746 
     747                 # a directory, same behaviour than os.path.isdir().
     748 
     749                 is_dir = False
     750 
     751 
     752 
     753             if is_dir:
     754 
     755                 dirs.append(entry.name)
     756 
     757             else:
     758 
     759                 nondirs.append(entry.name)
     760 
     761 
     762 
     763             if not topdown and is_dir:
     764 
     765                 # Bottom-up: recurse into sub-directory, but exclude symlinks to
     766 
     767                 # directories if followlinks is False
     768 
     769                 if followlinks:
     770 
     771                     walk_into = True
     772 
     773                 else:
     774 
     775                     try:
     776 
     777                         is_symlink = entry.is_symlink()
     778 
     779                     except OSError:
     780 
     781                         # If is_symlink() raises an OSError, consider that the
     782 
     783                         # entry is not a symbolic link, same behaviour than
     784 
     785                         # os.path.islink().
     786 
     787                         is_symlink = False
     788 
     789                     walk_into = not is_symlink
     790 
     791 
     792 
     793                 if walk_into:
     794 
     795                     walk_dirs.append(entry.path)
     796 
     797 
     798 
     799     # Yield before recursion if going top down
     800 
     801     if topdown:
     802 
     803         yield top, dirs, nondirs
     804 
     805 
     806 
     807         # Recurse into sub-directories
     808 
     809         islink, join = path.islink, path.join
     810 
     811         for dirname in dirs:
     812 
     813             new_path = join(top, dirname)
     814 
     815             # Issue #23605: os.path.islink() is used instead of caching
     816 
     817             # entry.is_symlink() result during the loop on os.scandir() because
     818 
     819             # the caller can replace the directory entry during the "yield"
     820 
     821             # above.
     822 
     823             if followlinks or not islink(new_path):
     824 
     825                 yield from walk(new_path, topdown, onerror, followlinks)
     826 
     827     else:
     828 
     829         # Recurse into sub-directories
     830 
     831         for new_path in walk_dirs:
     832 
     833             yield from walk(new_path, topdown, onerror, followlinks)
     834 
     835         # Yield after recursion if going bottom up
     836 
     837         yield top, dirs, nondirs
     838 
     839 
     840 
     841 __all__.append("walk")
     842 
     843 
     844 
     845 if {open, stat} <= supports_dir_fd and {scandir, stat} <= supports_fd:
     846 
     847 
     848 
     849     def fwalk(top=".", topdown=True, onerror=None, *, follow_symlinks=False, dir_fd=None):
     850 
     851         """Directory tree generator.
     852 
     853 
     854 
     855         This behaves exactly like walk(), except that it yields a 4-tuple
     856 
     857 
     858 
     859             dirpath, dirnames, filenames, dirfd
     860 
     861 
     862 
     863         `dirpath`, `dirnames` and `filenames` are identical to walk() output,
     864 
     865         and `dirfd` is a file descriptor referring to the directory `dirpath`.
     866 
     867 
     868 
     869         The advantage of fwalk() over walk() is that it's safe against symlink
     870 
     871         races (when follow_symlinks is False).
     872 
     873 
     874 
     875         If dir_fd is not None, it should be a file descriptor open to a directory,
     876 
     877           and top should be relative; top will then be relative to that directory.
     878 
     879           (dir_fd is always supported for fwalk.)
     880 
     881 
     882 
     883         Caution:
     884 
     885         Since fwalk() yields file descriptors, those are only valid until the
     886 
     887         next iteration step, so you should dup() them if you want to keep them
     888 
     889         for a longer period.
     890 
     891 
     892 
     893         Example:
     894 
     895 
     896 
     897         import os
     898 
     899         for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
     900 
     901             print(root, "consumes", end="")
     902 
     903             print(sum([os.stat(name, dir_fd=rootfd).st_size for name in files]),
     904 
     905                   end="")
     906 
     907             print("bytes in", len(files), "non-directory files")
     908 
     909             if 'CVS' in dirs:
     910 
     911                 dirs.remove('CVS')  # don't visit CVS directories
     912 
     913         """
     914 
     915         if not isinstance(top, int) or not hasattr(top, '__index__'):
     916 
     917             top = fspath(top)
     918 
     919         # Note: To guard against symlink races, we use the standard
     920 
     921         # lstat()/open()/fstat() trick.
     922 
     923         if not follow_symlinks:
     924 
     925             orig_st = stat(top, follow_symlinks=False, dir_fd=dir_fd)
     926 
     927         topfd = open(top, O_RDONLY, dir_fd=dir_fd)
     928 
     929         try:
     930 
     931             if (follow_symlinks or (st.S_ISDIR(orig_st.st_mode) and
     932 
     933                                     path.samestat(orig_st, stat(topfd)))):
     934 
     935                 yield from _fwalk(topfd, top, isinstance(top, bytes),
     936 
     937                                   topdown, onerror, follow_symlinks)
     938 
     939         finally:
     940 
     941             close(topfd)
     942 
     943 
     944 
     945     def _fwalk(topfd, toppath, isbytes, topdown, onerror, follow_symlinks):
     946 
     947         # Note: This uses O(depth of the directory tree) file descriptors: if
     948 
     949         # necessary, it can be adapted to only require O(1) FDs, see issue
     950 
     951         # #13734.
     952 
     953 
     954 
     955         scandir_it = scandir(topfd)
     956 
     957         dirs = []
     958 
     959         nondirs = []
     960 
     961         entries = None if topdown or follow_symlinks else []
     962 
     963         for entry in scandir_it:
     964 
     965             name = entry.name
     966 
     967             if isbytes:
     968 
     969                 name = fsencode(name)
     970 
     971             try:
     972 
     973                 if entry.is_dir():
     974 
     975                     dirs.append(name)
     976 
     977                     if entries is not None:
     978 
     979                         entries.append(entry)
     980 
     981                 else:
     982 
     983                     nondirs.append(name)
     984 
     985             except OSError:
     986 
     987                 try:
     988 
     989                     # Add dangling symlinks, ignore disappeared files
     990 
     991                     if entry.is_symlink():
     992 
     993                         nondirs.append(name)
     994 
     995                 except OSError:
     996 
     997                     pass
     998 
     999 
    1000 
    1001         if topdown:
    1002 
    1003             yield toppath, dirs, nondirs, topfd
    1004 
    1005 
    1006 
    1007         for name in dirs if entries is None else zip(dirs, entries):
    1008 
    1009             try:
    1010 
    1011                 if not follow_symlinks:
    1012 
    1013                     if topdown:
    1014 
    1015                         orig_st = stat(name, dir_fd=topfd, follow_symlinks=False)
    1016 
    1017                     else:
    1018 
    1019                         assert entries is not None
    1020 
    1021                         name, entry = name
    1022 
    1023                         orig_st = entry.stat(follow_symlinks=False)
    1024 
    1025                 dirfd = open(name, O_RDONLY, dir_fd=topfd)
    1026 
    1027             except OSError as err:
    1028 
    1029                 if onerror is not None:
    1030 
    1031                     onerror(err)
    1032 
    1033                 continue
    1034 
    1035             try:
    1036 
    1037                 if follow_symlinks or path.samestat(orig_st, stat(dirfd)):
    1038 
    1039                     dirpath = path.join(toppath, name)
    1040 
    1041                     yield from _fwalk(dirfd, dirpath, isbytes,
    1042 
    1043                                       topdown, onerror, follow_symlinks)
    1044 
    1045             finally:
    1046 
    1047                 close(dirfd)
    1048 
    1049 
    1050 
    1051         if not topdown:
    1052 
    1053             yield toppath, dirs, nondirs, topfd
    1054 
    1055 
    1056 
    1057     __all__.append("fwalk")
    1058 
    1059 
    1060 
    1061 # Make sure os.environ exists, at least
    1062 
    1063 try:
    1064 
    1065     environ
    1066 
    1067 except NameError:
    1068 
    1069     environ = {}
    1070 
    1071 
    1072 
    1073 def execl(file, *args):
    1074 
    1075     """execl(file, *args)
    1076 
    1077 
    1078 
    1079     Execute the executable file with argument list args, replacing the
    1080 
    1081     current process. """
    1082 
    1083     execv(file, args)
    1084 
    1085 
    1086 
    1087 def execle(file, *args):
    1088 
    1089     """execle(file, *args, env)
    1090 
    1091 
    1092 
    1093     Execute the executable file with argument list args and
    1094 
    1095     environment env, replacing the current process. """
    1096 
    1097     env = args[-1]
    1098 
    1099     execve(file, args[:-1], env)
    1100 
    1101 
    1102 
    1103 def execlp(file, *args):
    1104 
    1105     """execlp(file, *args)
    1106 
    1107 
    1108 
    1109     Execute the executable file (which is searched for along $PATH)
    1110 
    1111     with argument list args, replacing the current process. """
    1112 
    1113     execvp(file, args)
    1114 
    1115 
    1116 
    1117 def execlpe(file, *args):
    1118 
    1119     """execlpe(file, *args, env)
    1120 
    1121 
    1122 
    1123     Execute the executable file (which is searched for along $PATH)
    1124 
    1125     with argument list args and environment env, replacing the current
    1126 
    1127     process. """
    1128 
    1129     env = args[-1]
    1130 
    1131     execvpe(file, args[:-1], env)
    1132 
    1133 
    1134 
    1135 def execvp(file, args):
    1136 
    1137     """execvp(file, args)
    1138 
    1139 
    1140 
    1141     Execute the executable file (which is searched for along $PATH)
    1142 
    1143     with argument list args, replacing the current process.
    1144 
    1145     args may be a list or tuple of strings. """
    1146 
    1147     _execvpe(file, args)
    1148 
    1149 
    1150 
    1151 def execvpe(file, args, env):
    1152 
    1153     """execvpe(file, args, env)
    1154 
    1155 
    1156 
    1157     Execute the executable file (which is searched for along $PATH)
    1158 
    1159     with argument list args and environment env, replacing the
    1160 
    1161     current process.
    1162 
    1163     args may be a list or tuple of strings. """
    1164 
    1165     _execvpe(file, args, env)
    1166 
    1167 
    1168 
    1169 __all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
    1170 
    1171 
    1172 
    1173 def _execvpe(file, args, env=None):
    1174 
    1175     if env is not None:
    1176 
    1177         exec_func = execve
    1178 
    1179         argrest = (args, env)
    1180 
    1181     else:
    1182 
    1183         exec_func = execv
    1184 
    1185         argrest = (args,)
    1186 
    1187         env = environ
    1188 
    1189 
    1190 
    1191     if path.dirname(file):
    1192 
    1193         exec_func(file, *argrest)
    1194 
    1195         return
    1196 
    1197     saved_exc = None
    1198 
    1199     path_list = get_exec_path(env)
    1200 
    1201     if name != 'nt':
    1202 
    1203         file = fsencode(file)
    1204 
    1205         path_list = map(fsencode, path_list)
    1206 
    1207     for dir in path_list:
    1208 
    1209         fullname = path.join(dir, file)
    1210 
    1211         try:
    1212 
    1213             exec_func(fullname, *argrest)
    1214 
    1215         except (FileNotFoundError, NotADirectoryError) as e:
    1216 
    1217             last_exc = e
    1218 
    1219         except OSError as e:
    1220 
    1221             last_exc = e
    1222 
    1223             if saved_exc is None:
    1224 
    1225                 saved_exc = e
    1226 
    1227     if saved_exc is not None:
    1228 
    1229         raise saved_exc
    1230 
    1231     raise last_exc
    1232 
    1233 
    1234 
    1235 
    1236 
    1237 def get_exec_path(env=None):
    1238 
    1239     """Returns the sequence of directories that will be searched for the
    1240 
    1241     named executable (similar to a shell) when launching a process.
    1242 
    1243 
    1244 
    1245     *env* must be an environment variable dict or None.  If *env* is None,
    1246 
    1247     os.environ will be used.
    1248 
    1249     """
    1250 
    1251     # Use a local import instead of a global import to limit the number of
    1252 
    1253     # modules loaded at startup: the os module is always loaded at startup by
    1254 
    1255     # Python. It may also avoid a bootstrap issue.
    1256 
    1257     import warnings
    1258 
    1259 
    1260 
    1261     if env is None:
    1262 
    1263         env = environ
    1264 
    1265 
    1266 
    1267     # {b'PATH': ...}.get('PATH') and {'PATH': ...}.get(b'PATH') emit a
    1268 
    1269     # BytesWarning when using python -b or python -bb: ignore the warning
    1270 
    1271     with warnings.catch_warnings():
    1272 
    1273         warnings.simplefilter("ignore", BytesWarning)
    1274 
    1275 
    1276 
    1277         try:
    1278 
    1279             path_list = env.get('PATH')
    1280 
    1281         except TypeError:
    1282 
    1283             path_list = None
    1284 
    1285 
    1286 
    1287         if supports_bytes_environ:
    1288 
    1289             try:
    1290 
    1291                 path_listb = env[b'PATH']
    1292 
    1293             except (KeyError, TypeError):
    1294 
    1295                 pass
    1296 
    1297             else:
    1298 
    1299                 if path_list is not None:
    1300 
    1301                     raise ValueError(
    1302 
    1303                         "env cannot contain 'PATH' and b'PATH' keys")
    1304 
    1305                 path_list = path_listb
    1306 
    1307 
    1308 
    1309             if path_list is not None and isinstance(path_list, bytes):
    1310 
    1311                 path_list = fsdecode(path_list)
    1312 
    1313 
    1314 
    1315     if path_list is None:
    1316 
    1317         path_list = defpath
    1318 
    1319     return path_list.split(pathsep)
    1320 
    1321 
    1322 
    1323 
    1324 
    1325 # Change environ to automatically call putenv(), unsetenv if they exist.
    1326 
    1327 from _collections_abc import MutableMapping
    1328 
    1329 
    1330 
    1331 class _Environ(MutableMapping):
    1332 
    1333     def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue, putenv, unsetenv):
    1334 
    1335         self.encodekey = encodekey
    1336 
    1337         self.decodekey = decodekey
    1338 
    1339         self.encodevalue = encodevalue
    1340 
    1341         self.decodevalue = decodevalue
    1342 
    1343         self.putenv = putenv
    1344 
    1345         self.unsetenv = unsetenv
    1346 
    1347         self._data = data
    1348 
    1349 
    1350 
    1351     def __getitem__(self, key):
    1352 
    1353         try:
    1354 
    1355             value = self._data[self.encodekey(key)]
    1356 
    1357         except KeyError:
    1358 
    1359             # raise KeyError with the original key value
    1360 
    1361             raise KeyError(key) from None
    1362 
    1363         return self.decodevalue(value)
    1364 
    1365 
    1366 
    1367     def __setitem__(self, key, value):
    1368 
    1369         key = self.encodekey(key)
    1370 
    1371         value = self.encodevalue(value)
    1372 
    1373         self.putenv(key, value)
    1374 
    1375         self._data[key] = value
    1376 
    1377 
    1378 
    1379     def __delitem__(self, key):
    1380 
    1381         encodedkey = self.encodekey(key)
    1382 
    1383         self.unsetenv(encodedkey)
    1384 
    1385         try:
    1386 
    1387             del self._data[encodedkey]
    1388 
    1389         except KeyError:
    1390 
    1391             # raise KeyError with the original key value
    1392 
    1393             raise KeyError(key) from None
    1394 
    1395 
    1396 
    1397     def __iter__(self):
    1398 
    1399         # list() from dict object is an atomic operation
    1400 
    1401         keys = list(self._data)
    1402 
    1403         for key in keys:
    1404 
    1405             yield self.decodekey(key)
    1406 
    1407 
    1408 
    1409     def __len__(self):
    1410 
    1411         return len(self._data)
    1412 
    1413 
    1414 
    1415     def __repr__(self):
    1416 
    1417         return 'environ({{{}}})'.format(', '.join(
    1418 
    1419             ('{!r}: {!r}'.format(self.decodekey(key), self.decodevalue(value))
    1420 
    1421             for key, value in self._data.items())))
    1422 
    1423 
    1424 
    1425     def copy(self):
    1426 
    1427         return dict(self)
    1428 
    1429 
    1430 
    1431     def setdefault(self, key, value):
    1432 
    1433         if key not in self:
    1434 
    1435             self[key] = value
    1436 
    1437         return self[key]
    1438 
    1439 
    1440 
    1441 try:
    1442 
    1443     _putenv = putenv
    1444 
    1445 except NameError:
    1446 
    1447     _putenv = lambda key, value: None
    1448 
    1449 else:
    1450 
    1451     if "putenv" not in __all__:
    1452 
    1453         __all__.append("putenv")
    1454 
    1455 
    1456 
    1457 try:
    1458 
    1459     _unsetenv = unsetenv
    1460 
    1461 except NameError:
    1462 
    1463     _unsetenv = lambda key: _putenv(key, "")
    1464 
    1465 else:
    1466 
    1467     if "unsetenv" not in __all__:
    1468 
    1469         __all__.append("unsetenv")
    1470 
    1471 
    1472 
    1473 def _createenviron():
    1474 
    1475     if name == 'nt':
    1476 
    1477         # Where Env Var Names Must Be UPPERCASE
    1478 
    1479         def check_str(value):
    1480 
    1481             if not isinstance(value, str):
    1482 
    1483                 raise TypeError("str expected, not %s" % type(value).__name__)
    1484 
    1485             return value
    1486 
    1487         encode = check_str
    1488 
    1489         decode = str
    1490 
    1491         def encodekey(key):
    1492 
    1493             return encode(key).upper()
    1494 
    1495         data = {}
    1496 
    1497         for key, value in environ.items():
    1498 
    1499             data[encodekey(key)] = value
    1500 
    1501     else:
    1502 
    1503         # Where Env Var Names Can Be Mixed Case
    1504 
    1505         encoding = sys.getfilesystemencoding()
    1506 
    1507         def encode(value):
    1508 
    1509             if not isinstance(value, str):
    1510 
    1511                 raise TypeError("str expected, not %s" % type(value).__name__)
    1512 
    1513             return value.encode(encoding, 'surrogateescape')
    1514 
    1515         def decode(value):
    1516 
    1517             return value.decode(encoding, 'surrogateescape')
    1518 
    1519         encodekey = encode
    1520 
    1521         data = environ
    1522 
    1523     return _Environ(data,
    1524 
    1525         encodekey, decode,
    1526 
    1527         encode, decode,
    1528 
    1529         _putenv, _unsetenv)
    1530 
    1531 
    1532 
    1533 # unicode environ
    1534 
    1535 environ = _createenviron()
    1536 
    1537 del _createenviron
    1538 
    1539 
    1540 
    1541 
    1542 
    1543 def getenv(key, default=None):
    1544 
    1545     """Get an environment variable, return None if it doesn't exist.
    1546 
    1547     The optional second argument can specify an alternate default.
    1548 
    1549     key, default and the result are str."""
    1550 
    1551     return environ.get(key, default)
    1552 
    1553 
    1554 
    1555 supports_bytes_environ = (name != 'nt')
    1556 
    1557 __all__.extend(("getenv", "supports_bytes_environ"))
    1558 
    1559 
    1560 
    1561 if supports_bytes_environ:
    1562 
    1563     def _check_bytes(value):
    1564 
    1565         if not isinstance(value, bytes):
    1566 
    1567             raise TypeError("bytes expected, not %s" % type(value).__name__)
    1568 
    1569         return value
    1570 
    1571 
    1572 
    1573     # bytes environ
    1574 
    1575     environb = _Environ(environ._data,
    1576 
    1577         _check_bytes, bytes,
    1578 
    1579         _check_bytes, bytes,
    1580 
    1581         _putenv, _unsetenv)
    1582 
    1583     del _check_bytes
    1584 
    1585 
    1586 
    1587     def getenvb(key, default=None):
    1588 
    1589         """Get an environment variable, return None if it doesn't exist.
    1590 
    1591         The optional second argument can specify an alternate default.
    1592 
    1593         key, default and the result are bytes."""
    1594 
    1595         return environb.get(key, default)
    1596 
    1597 
    1598 
    1599     __all__.extend(("environb", "getenvb"))
    1600 
    1601 
    1602 
    1603 def _fscodec():
    1604 
    1605     encoding = sys.getfilesystemencoding()
    1606 
    1607     errors = sys.getfilesystemencodeerrors()
    1608 
    1609 
    1610 
    1611     def fsencode(filename):
    1612 
    1613         """Encode filename (an os.PathLike, bytes, or str) to the filesystem
    1614 
    1615         encoding with 'surrogateescape' error handler, return bytes unchanged.
    1616 
    1617         On Windows, use 'strict' error handler if the file system encoding is
    1618 
    1619         'mbcs' (which is the default encoding).
    1620 
    1621         """
    1622 
    1623         filename = fspath(filename)  # Does type-checking of `filename`.
    1624 
    1625         if isinstance(filename, str):
    1626 
    1627             return filename.encode(encoding, errors)
    1628 
    1629         else:
    1630 
    1631             return filename
    1632 
    1633 
    1634 
    1635     def fsdecode(filename):
    1636 
    1637         """Decode filename (an os.PathLike, bytes, or str) from the filesystem
    1638 
    1639         encoding with 'surrogateescape' error handler, return str unchanged. On
    1640 
    1641         Windows, use 'strict' error handler if the file system encoding is
    1642 
    1643         'mbcs' (which is the default encoding).
    1644 
    1645         """
    1646 
    1647         filename = fspath(filename)  # Does type-checking of `filename`.
    1648 
    1649         if isinstance(filename, bytes):
    1650 
    1651             return filename.decode(encoding, errors)
    1652 
    1653         else:
    1654 
    1655             return filename
    1656 
    1657 
    1658 
    1659     return fsencode, fsdecode
    1660 
    1661 
    1662 
    1663 fsencode, fsdecode = _fscodec()
    1664 
    1665 del _fscodec
    1666 
    1667 
    1668 
    1669 # Supply spawn*() (probably only for Unix)
    1670 
    1671 if _exists("fork") and not _exists("spawnv") and _exists("execv"):
    1672 
    1673 
    1674 
    1675     P_WAIT = 0
    1676 
    1677     P_NOWAIT = P_NOWAITO = 1
    1678 
    1679 
    1680 
    1681     __all__.extend(["P_WAIT", "P_NOWAIT", "P_NOWAITO"])
    1682 
    1683 
    1684 
    1685     # XXX Should we support P_DETACH?  I suppose it could fork()**2
    1686 
    1687     # and close the std I/O streams.  Also, P_OVERLAY is the same
    1688 
    1689     # as execv*()?
    1690 
    1691 
    1692 
    1693     def _spawnvef(mode, file, args, env, func):
    1694 
    1695         # Internal helper; func is the exec*() function to use
    1696 
    1697         if not isinstance(args, (tuple, list)):
    1698 
    1699             raise TypeError('argv must be a tuple or a list')
    1700 
    1701         if not args or not args[0]:
    1702 
    1703             raise ValueError('argv first element cannot be empty')
    1704 
    1705         pid = fork()
    1706 
    1707         if not pid:
    1708 
    1709             # Child
    1710 
    1711             try:
    1712 
    1713                 if env is None:
    1714 
    1715                     func(file, args)
    1716 
    1717                 else:
    1718 
    1719                     func(file, args, env)
    1720 
    1721             except:
    1722 
    1723                 _exit(127)
    1724 
    1725         else:
    1726 
    1727             # Parent
    1728 
    1729             if mode == P_NOWAIT:
    1730 
    1731                 return pid # Caller is responsible for waiting!
    1732 
    1733             while 1:
    1734 
    1735                 wpid, sts = waitpid(pid, 0)
    1736 
    1737                 if WIFSTOPPED(sts):
    1738 
    1739                     continue
    1740 
    1741                 elif WIFSIGNALED(sts):
    1742 
    1743                     return -WTERMSIG(sts)
    1744 
    1745                 elif WIFEXITED(sts):
    1746 
    1747                     return WEXITSTATUS(sts)
    1748 
    1749                 else:
    1750 
    1751                     raise OSError("Not stopped, signaled or exited???")
    1752 
    1753 
    1754 
    1755     def spawnv(mode, file, args):
    1756 
    1757         """spawnv(mode, file, args) -> integer
    1758 
    1759 
    1760 
    1761 Execute file with arguments from args in a subprocess.
    1762 
    1763 If mode == P_NOWAIT return the pid of the process.
    1764 
    1765 If mode == P_WAIT return the process's exit code if it exits normally;
    1766 
    1767 otherwise return -SIG, where SIG is the signal that killed it. """
    1768 
    1769         return _spawnvef(mode, file, args, None, execv)
    1770 
    1771 
    1772 
    1773     def spawnve(mode, file, args, env):
    1774 
    1775         """spawnve(mode, file, args, env) -> integer
    1776 
    1777 
    1778 
    1779 Execute file with arguments from args in a subprocess with the
    1780 
    1781 specified environment.
    1782 
    1783 If mode == P_NOWAIT return the pid of the process.
    1784 
    1785 If mode == P_WAIT return the process's exit code if it exits normally;
    1786 
    1787 otherwise return -SIG, where SIG is the signal that killed it. """
    1788 
    1789         return _spawnvef(mode, file, args, env, execve)
    1790 
    1791 
    1792 
    1793     # Note: spawnvp[e] isn't currently supported on Windows
    1794 
    1795 
    1796 
    1797     def spawnvp(mode, file, args):
    1798 
    1799         """spawnvp(mode, file, args) -> integer
    1800 
    1801 
    1802 
    1803 Execute file (which is looked for along $PATH) with arguments from
    1804 
    1805 args in a subprocess.
    1806 
    1807 If mode == P_NOWAIT return the pid of the process.
    1808 
    1809 If mode == P_WAIT return the process's exit code if it exits normally;
    1810 
    1811 otherwise return -SIG, where SIG is the signal that killed it. """
    1812 
    1813         return _spawnvef(mode, file, args, None, execvp)
    1814 
    1815 
    1816 
    1817     def spawnvpe(mode, file, args, env):
    1818 
    1819         """spawnvpe(mode, file, args, env) -> integer
    1820 
    1821 
    1822 
    1823 Execute file (which is looked for along $PATH) with arguments from
    1824 
    1825 args in a subprocess with the supplied environment.
    1826 
    1827 If mode == P_NOWAIT return the pid of the process.
    1828 
    1829 If mode == P_WAIT return the process's exit code if it exits normally;
    1830 
    1831 otherwise return -SIG, where SIG is the signal that killed it. """
    1832 
    1833         return _spawnvef(mode, file, args, env, execvpe)
    1834 
    1835 
    1836 
    1837 
    1838 
    1839     __all__.extend(["spawnv", "spawnve", "spawnvp", "spawnvpe"])
    1840 
    1841 
    1842 
    1843 
    1844 
    1845 if _exists("spawnv"):
    1846 
    1847     # These aren't supplied by the basic Windows code
    1848 
    1849     # but can be easily implemented in Python
    1850 
    1851 
    1852 
    1853     def spawnl(mode, file, *args):
    1854 
    1855         """spawnl(mode, file, *args) -> integer
    1856 
    1857 
    1858 
    1859 Execute file with arguments from args in a subprocess.
    1860 
    1861 If mode == P_NOWAIT return the pid of the process.
    1862 
    1863 If mode == P_WAIT return the process's exit code if it exits normally;
    1864 
    1865 otherwise return -SIG, where SIG is the signal that killed it. """
    1866 
    1867         return spawnv(mode, file, args)
    1868 
    1869 
    1870 
    1871     def spawnle(mode, file, *args):
    1872 
    1873         """spawnle(mode, file, *args, env) -> integer
    1874 
    1875 
    1876 
    1877 Execute file with arguments from args in a subprocess with the
    1878 
    1879 supplied environment.
    1880 
    1881 If mode == P_NOWAIT return the pid of the process.
    1882 
    1883 If mode == P_WAIT return the process's exit code if it exits normally;
    1884 
    1885 otherwise return -SIG, where SIG is the signal that killed it. """
    1886 
    1887         env = args[-1]
    1888 
    1889         return spawnve(mode, file, args[:-1], env)
    1890 
    1891 
    1892 
    1893 
    1894 
    1895     __all__.extend(["spawnl", "spawnle"])
    1896 
    1897 
    1898 
    1899 
    1900 
    1901 if _exists("spawnvp"):
    1902 
    1903     # At the moment, Windows doesn't implement spawnvp[e],
    1904 
    1905     # so it won't have spawnlp[e] either.
    1906 
    1907     def spawnlp(mode, file, *args):
    1908 
    1909         """spawnlp(mode, file, *args) -> integer
    1910 
    1911 
    1912 
    1913 Execute file (which is looked for along $PATH) with arguments from
    1914 
    1915 args in a subprocess with the supplied environment.
    1916 
    1917 If mode == P_NOWAIT return the pid of the process.
    1918 
    1919 If mode == P_WAIT return the process's exit code if it exits normally;
    1920 
    1921 otherwise return -SIG, where SIG is the signal that killed it. """
    1922 
    1923         return spawnvp(mode, file, args)
    1924 
    1925 
    1926 
    1927     def spawnlpe(mode, file, *args):
    1928 
    1929         """spawnlpe(mode, file, *args, env) -> integer
    1930 
    1931 
    1932 
    1933 Execute file (which is looked for along $PATH) with arguments from
    1934 
    1935 args in a subprocess with the supplied environment.
    1936 
    1937 If mode == P_NOWAIT return the pid of the process.
    1938 
    1939 If mode == P_WAIT return the process's exit code if it exits normally;
    1940 
    1941 otherwise return -SIG, where SIG is the signal that killed it. """
    1942 
    1943         env = args[-1]
    1944 
    1945         return spawnvpe(mode, file, args[:-1], env)
    1946 
    1947 
    1948 
    1949 
    1950 
    1951     __all__.extend(["spawnlp", "spawnlpe"])
    1952 
    1953 
    1954 
    1955 
    1956 
    1957 # Supply os.popen()
    1958 
    1959 def popen(cmd, mode="r", buffering=-1):
    1960 
    1961     if not isinstance(cmd, str):
    1962 
    1963         raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
    1964 
    1965     if mode not in ("r", "w"):
    1966 
    1967         raise ValueError("invalid mode %r" % mode)
    1968 
    1969     if buffering == 0 or buffering is None:
    1970 
    1971         raise ValueError("popen() does not support unbuffered streams")
    1972 
    1973     import subprocess, io
    1974 
    1975     if mode == "r":
    1976 
    1977         proc = subprocess.Popen(cmd,
    1978 
    1979                                 shell=True,
    1980 
    1981                                 stdout=subprocess.PIPE,
    1982 
    1983                                 bufsize=buffering)
    1984 
    1985         return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
    1986 
    1987     else:
    1988 
    1989         proc = subprocess.Popen(cmd,
    1990 
    1991                                 shell=True,
    1992 
    1993                                 stdin=subprocess.PIPE,
    1994 
    1995                                 bufsize=buffering)
    1996 
    1997         return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
    1998 
    1999 
    2000 
    2001 # Helper for popen() -- a proxy for a file whose close waits for the process
    2002 
    2003 class _wrap_close:
    2004 
    2005     def __init__(self, stream, proc):
    2006 
    2007         self._stream = stream
    2008 
    2009         self._proc = proc
    2010 
    2011     def close(self):
    2012 
    2013         self._stream.close()
    2014 
    2015         returncode = self._proc.wait()
    2016 
    2017         if returncode == 0:
    2018 
    2019             return None
    2020 
    2021         if name == 'nt':
    2022 
    2023             return returncode
    2024 
    2025         else:
    2026 
    2027             return returncode << 8  # Shift left to match old behavior
    2028 
    2029     def __enter__(self):
    2030 
    2031         return self
    2032 
    2033     def __exit__(self, *args):
    2034 
    2035         self.close()
    2036 
    2037     def __getattr__(self, name):
    2038 
    2039         return getattr(self._stream, name)
    2040 
    2041     def __iter__(self):
    2042 
    2043         return iter(self._stream)
    2044 
    2045 
    2046 
    2047 # Supply os.fdopen()
    2048 
    2049 def fdopen(fd, *args, **kwargs):
    2050 
    2051     if not isinstance(fd, int):
    2052 
    2053         raise TypeError("invalid fd type (%s, expected integer)" % type(fd))
    2054 
    2055     import io
    2056 
    2057     return io.open(fd, *args, **kwargs)
    2058 
    2059 
    2060 
    2061 
    2062 
    2063 # For testing purposes, make sure the function is available when the C
    2064 
    2065 # implementation exists.
    2066 
    2067 def _fspath(path):
    2068 
    2069     """Return the path representation of a path-like object.
    2070 
    2071 
    2072 
    2073     If str or bytes is passed in, it is returned unchanged. Otherwise the
    2074 
    2075     os.PathLike interface is used to get the path representation. If the
    2076 
    2077     path representation is not str or bytes, TypeError is raised. If the
    2078 
    2079     provided path is not str, bytes, or os.PathLike, TypeError is raised.
    2080 
    2081     """
    2082 
    2083     if isinstance(path, (str, bytes)):
    2084 
    2085         return path
    2086 
    2087 
    2088 
    2089     # Work from the object's type to match method resolution of other magic
    2090 
    2091     # methods.
    2092 
    2093     path_type = type(path)
    2094 
    2095     try:
    2096 
    2097         path_repr = path_type.__fspath__(path)
    2098 
    2099     except AttributeError:
    2100 
    2101         if hasattr(path_type, '__fspath__'):
    2102 
    2103             raise
    2104 
    2105         else:
    2106 
    2107             raise TypeError("expected str, bytes or os.PathLike object, "
    2108 
    2109                             "not " + path_type.__name__)
    2110 
    2111     if isinstance(path_repr, (str, bytes)):
    2112 
    2113         return path_repr
    2114 
    2115     else:
    2116 
    2117         raise TypeError("expected {}.__fspath__() to return str or bytes, "
    2118 
    2119                         "not {}".format(path_type.__name__,
    2120 
    2121                                         type(path_repr).__name__))
    2122 
    2123 
    2124 
    2125 # If there is no C implementation, make the pure Python version the
    2126 
    2127 # implementation as transparently as possible.
    2128 
    2129 if not _exists('fspath'):
    2130 
    2131     fspath = _fspath
    2132 
    2133     fspath.__name__ = "fspath"
    2134 
    2135 
    2136 
    2137 
    2138 
    2139 class PathLike(abc.ABC):
    2140 
    2141 
    2142 
    2143     """Abstract base class for implementing the file system path protocol."""
    2144 
    2145 
    2146 
    2147     @abc.abstractmethod
    2148 
    2149     def __fspath__(self):
    2150 
    2151         """Return the file system path representation of the object."""
    2152 
    2153         raise NotImplementedError
    2154 
    2155 
    2156 
    2157     @classmethod
    2158 
    2159     def __subclasshook__(cls, subclass):
    2160 
    2161         if cls is PathLike:
    2162 
    2163             return _check_methods(subclass, '__fspath__')
    2164 
    2165         return NotImplemented
    View Code

    参考资料:

    https://docs.python.org/zh-cn/3.7/library/os.html#process-management

    https://github.com/python/cpython/blob/3.7/Lib/os.py

  • 相关阅读:
    Windows Server 2008 R2 Enterprise 安装.NET Framework 4.0
    layer弹层content写错导致div复制了一次,导致id失效 $().val() 获取不到dispaly:none div里表单的值
    IIS 注册.NET Framework 4.0 命令
    记一次神秘又刺激的装机
    HTTP Error 503. The service is unavailable.
    找到多个与名为“Home”的控制器匹配的类型。
    Discuz论坛广告横幅大图在百度app内无法显示,百度app默认开启了广告屏蔽
    解决Antimalware Service Executable CPU,内存占用高的问题
    Discuz 部署,500 – 内部服务器错误。 您查找的资源存在问题,因而无法显示。
    IIS部署网站只有首页能访问,其他链接失效/运行.net+Access网站-可能原因:IIS未启用32位应用程序模式
  • 原文地址:https://www.cnblogs.com/zhiminyu/p/12612527.html
Copyright © 2011-2022 走看看