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 ('\r' or '\n' or '\r\n') 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 = '\n' 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 = '\r\n' 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
参考资料:
https://docs.python.org/zh-cn/3.7/library/os.html#process-management
https://github.com/python/cpython/blob/3.7/Lib/os.py
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)