• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1:mod:`shutil` --- High-level file operations
2============================================
3
4.. module:: shutil
5   :synopsis: High-level file operations, including copying.
6
7.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
8.. partly based on the docstrings
9
10**Source code:** :source:`Lib/shutil.py`
11
12.. index::
13   single: file; copying
14   single: copying files
15
16--------------
17
18The :mod:`shutil` module offers a number of high-level operations on files and
19collections of files.  In particular, functions are provided  which support file
20copying and removal. For operations on individual files, see also the
21:mod:`os` module.
22
23.. warning::
24
25   Even the higher-level file copying functions (:func:`shutil.copy`,
26   :func:`shutil.copy2`) cannot copy all file metadata.
27
28   On POSIX platforms, this means that file owner and group are lost as well
29   as ACLs.  On Mac OS, the resource fork and other metadata are not used.
30   This means that resources will be lost and file type and creator codes will
31   not be correct. On Windows, file owners, ACLs and alternate data streams
32   are not copied.
33
34
35.. _file-operations:
36
37Directory and files operations
38------------------------------
39
40.. function:: copyfileobj(fsrc, fdst[, length])
41
42   Copy the contents of the file-like object *fsrc* to the file-like object *fdst*.
43   The integer *length*, if given, is the buffer size. In particular, a negative
44   *length* value means to copy the data without looping over the source data in
45   chunks; by default the data is read in chunks to avoid uncontrolled memory
46   consumption. Note that if the current file position of the *fsrc* object is not
47   0, only the contents from the current file position to the end of the file will
48   be copied.
49
50
51.. function:: copyfile(src, dst, *, follow_symlinks=True)
52
53   Copy the contents (no metadata) of the file named *src* to a file named
54   *dst* and return *dst*.  *src* and *dst* are path names given as strings.
55   *dst* must be the complete target file name; look at :func:`shutil.copy`
56   for a copy that accepts a target directory path.  If *src* and *dst*
57   specify the same file, :exc:`SameFileError` is raised.
58
59   The destination location must be writable; otherwise, an :exc:`OSError`
60   exception will be raised. If *dst* already exists, it will be replaced.
61   Special files such as character or block devices and pipes cannot be
62   copied with this function.
63
64   If *follow_symlinks* is false and *src* is a symbolic link,
65   a new symbolic link will be created instead of copying the
66   file *src* points to.
67
68   .. versionchanged:: 3.3
69      :exc:`IOError` used to be raised instead of :exc:`OSError`.
70      Added *follow_symlinks* argument.
71      Now returns *dst*.
72
73   .. versionchanged:: 3.4
74      Raise :exc:`SameFileError` instead of :exc:`Error`.  Since the former is
75      a subclass of the latter, this change is backward compatible.
76
77
78.. exception:: SameFileError
79
80   This exception is raised if source and destination in :func:`copyfile`
81   are the same file.
82
83   .. versionadded:: 3.4
84
85
86.. function:: copymode(src, dst, *, follow_symlinks=True)
87
88   Copy the permission bits from *src* to *dst*.  The file contents, owner, and
89   group are unaffected.  *src* and *dst* are path names given as strings.
90   If *follow_symlinks* is false, and both *src* and *dst* are symbolic links,
91   :func:`copymode` will attempt to modify the mode of *dst* itself (rather
92   than the file it points to).  This functionality is not available on every
93   platform; please see :func:`copystat` for more information.  If
94   :func:`copymode` cannot modify symbolic links on the local platform, and it
95   is asked to do so, it will do nothing and return.
96
97   .. versionchanged:: 3.3
98      Added *follow_symlinks* argument.
99
100.. function:: copystat(src, dst, *, follow_symlinks=True)
101
102   Copy the permission bits, last access time, last modification time, and
103   flags from *src* to *dst*.  On Linux, :func:`copystat` also copies the
104   "extended attributes" where possible.  The file contents, owner, and
105   group are unaffected.  *src* and *dst* are path names given as strings.
106
107   If *follow_symlinks* is false, and *src* and *dst* both
108   refer to symbolic links, :func:`copystat` will operate on
109   the symbolic links themselves rather than the files the
110   symbolic links refer to—reading the information from the
111   *src* symbolic link, and writing the information to the
112   *dst* symbolic link.
113
114   .. note::
115
116      Not all platforms provide the ability to examine and
117      modify symbolic links.  Python itself can tell you what
118      functionality is locally available.
119
120      * If ``os.chmod in os.supports_follow_symlinks`` is
121        ``True``, :func:`copystat` can modify the permission
122        bits of a symbolic link.
123
124      * If ``os.utime in os.supports_follow_symlinks`` is
125        ``True``, :func:`copystat` can modify the last access
126        and modification times of a symbolic link.
127
128      * If ``os.chflags in os.supports_follow_symlinks`` is
129        ``True``, :func:`copystat` can modify the flags of
130        a symbolic link.  (``os.chflags`` is not available on
131        all platforms.)
132
133      On platforms where some or all of this functionality
134      is unavailable, when asked to modify a symbolic link,
135      :func:`copystat` will copy everything it can.
136      :func:`copystat` never returns failure.
137
138      Please see :data:`os.supports_follow_symlinks`
139      for more information.
140
141   .. versionchanged:: 3.3
142      Added *follow_symlinks* argument and support for Linux extended attributes.
143
144.. function:: copy(src, dst, *, follow_symlinks=True)
145
146   Copies the file *src* to the file or directory *dst*.  *src* and *dst*
147   should be strings.  If *dst* specifies a directory, the file will be
148   copied into *dst* using the base filename from *src*.  Returns the
149   path to the newly created file.
150
151   If *follow_symlinks* is false, and *src* is a symbolic link,
152   *dst* will be created as a symbolic link.  If *follow_symlinks*
153   is true and *src* is a symbolic link, *dst* will be a copy of
154   the file *src* refers to.
155
156   :func:`copy` copies the file data and the file's permission
157   mode (see :func:`os.chmod`).  Other metadata, like the
158   file's creation and modification times, is not preserved.
159   To preserve all file metadata from the original, use
160   :func:`~shutil.copy2` instead.
161
162   .. versionchanged:: 3.3
163      Added *follow_symlinks* argument.
164      Now returns path to the newly created file.
165
166.. function:: copy2(src, dst, *, follow_symlinks=True)
167
168   Identical to :func:`~shutil.copy` except that :func:`copy2`
169   also attempts to preserve all file metadata.
170
171   When *follow_symlinks* is false, and *src* is a symbolic
172   link, :func:`copy2` attempts to copy all metadata from the
173   *src* symbolic link to the newly-created *dst* symbolic link.
174   However, this functionality is not available on all platforms.
175   On platforms where some or all of this functionality is
176   unavailable, :func:`copy2` will preserve all the metadata
177   it can; :func:`copy2` never returns failure.
178
179   :func:`copy2` uses :func:`copystat` to copy the file metadata.
180   Please see :func:`copystat` for more information
181   about platform support for modifying symbolic link metadata.
182
183   .. versionchanged:: 3.3
184      Added *follow_symlinks* argument, try to copy extended
185      file system attributes too (currently Linux only).
186      Now returns path to the newly created file.
187
188.. function:: ignore_patterns(\*patterns)
189
190   This factory function creates a function that can be used as a callable for
191   :func:`copytree`\'s *ignore* argument, ignoring files and directories that
192   match one of the glob-style *patterns* provided.  See the example below.
193
194
195.. function:: copytree(src, dst, symlinks=False, ignore=None, \
196              copy_function=copy2, ignore_dangling_symlinks=False)
197
198   Recursively copy an entire directory tree rooted at *src*, returning the
199   destination directory.  The destination
200   directory, named by *dst*, must not already exist; it will be created as
201   well as missing parent directories.  Permissions and times of directories
202   are copied with :func:`copystat`, individual files are copied using
203   :func:`shutil.copy2`.
204
205   If *symlinks* is true, symbolic links in the source tree are represented as
206   symbolic links in the new tree and the metadata of the original links will
207   be copied as far as the platform allows; if false or omitted, the contents
208   and metadata of the linked files are copied to the new tree.
209
210   When *symlinks* is false, if the file pointed by the symlink doesn't
211   exist, an exception will be added in the list of errors raised in
212   an :exc:`Error` exception at the end of the copy process.
213   You can set the optional *ignore_dangling_symlinks* flag to true if you
214   want to silence this exception. Notice that this option has no effect
215   on platforms that don't support :func:`os.symlink`.
216
217   If *ignore* is given, it must be a callable that will receive as its
218   arguments the directory being visited by :func:`copytree`, and a list of its
219   contents, as returned by :func:`os.listdir`.  Since :func:`copytree` is
220   called recursively, the *ignore* callable will be called once for each
221   directory that is copied.  The callable must return a sequence of directory
222   and file names relative to the current directory (i.e. a subset of the items
223   in its second argument); these names will then be ignored in the copy
224   process.  :func:`ignore_patterns` can be used to create such a callable that
225   ignores names based on glob-style patterns.
226
227   If exception(s) occur, an :exc:`Error` is raised with a list of reasons.
228
229   If *copy_function* is given, it must be a callable that will be used to copy
230   each file. It will be called with the source path and the destination path
231   as arguments. By default, :func:`shutil.copy2` is used, but any function
232   that supports the same signature (like :func:`shutil.copy`) can be used.
233
234   .. versionchanged:: 3.3
235      Copy metadata when *symlinks* is false.
236      Now returns *dst*.
237
238   .. versionchanged:: 3.2
239      Added the *copy_function* argument to be able to provide a custom copy
240      function.
241      Added the *ignore_dangling_symlinks* argument to silent dangling symlinks
242      errors when *symlinks* is false.
243
244
245.. function:: rmtree(path, ignore_errors=False, onerror=None)
246
247   .. index:: single: directory; deleting
248
249   Delete an entire directory tree; *path* must point to a directory (but not a
250   symbolic link to a directory).  If *ignore_errors* is true, errors resulting
251   from failed removals will be ignored; if false or omitted, such errors are
252   handled by calling a handler specified by *onerror* or, if that is omitted,
253   they raise an exception.
254
255   .. note::
256
257      On platforms that support the necessary fd-based functions a symlink
258      attack resistant version of :func:`rmtree` is used by default.  On other
259      platforms, the :func:`rmtree` implementation is susceptible to a symlink
260      attack: given proper timing and circumstances, attackers can manipulate
261      symlinks on the filesystem to delete files they wouldn't be able to access
262      otherwise.  Applications can use the :data:`rmtree.avoids_symlink_attacks`
263      function attribute to determine which case applies.
264
265   If *onerror* is provided, it must be a callable that accepts three
266   parameters: *function*, *path*, and *excinfo*.
267
268   The first parameter, *function*, is the function which raised the exception;
269   it depends on the platform and implementation.  The second parameter,
270   *path*, will be the path name passed to *function*.  The third parameter,
271   *excinfo*, will be the exception information returned by
272   :func:`sys.exc_info`.  Exceptions raised by *onerror* will not be caught.
273
274   .. versionchanged:: 3.3
275      Added a symlink attack resistant version that is used automatically
276      if platform supports fd-based functions.
277
278   .. attribute:: rmtree.avoids_symlink_attacks
279
280      Indicates whether the current platform and implementation provides a
281      symlink attack resistant version of :func:`rmtree`.  Currently this is
282      only true for platforms supporting fd-based directory access functions.
283
284      .. versionadded:: 3.3
285
286
287.. function:: move(src, dst, copy_function=copy2)
288
289   Recursively move a file or directory (*src*) to another location (*dst*)
290   and return the destination.
291
292   If the destination is an existing directory, then *src* is moved inside that
293   directory. If the destination already exists but is not a directory, it may
294   be overwritten depending on :func:`os.rename` semantics.
295
296   If the destination is on the current filesystem, then :func:`os.rename` is
297   used. Otherwise, *src* is copied to *dst* using *copy_function* and then
298   removed.  In case of symlinks, a new symlink pointing to the target of *src*
299   will be created in or as *dst* and *src* will be removed.
300
301   If *copy_function* is given, it must be a callable that takes two arguments
302   *src* and *dst*, and will be used to copy *src* to *dest* if
303   :func:`os.rename` cannot be used.  If the source is a directory,
304   :func:`copytree` is called, passing it the :func:`copy_function`. The
305   default *copy_function* is :func:`copy2`.  Using :func:`copy` as the
306   *copy_function* allows the move to succeed when it is not possible to also
307   copy the metadata, at the expense of not copying any of the metadata.
308
309   .. versionchanged:: 3.3
310      Added explicit symlink handling for foreign filesystems, thus adapting
311      it to the behavior of GNU's :program:`mv`.
312      Now returns *dst*.
313
314   .. versionchanged:: 3.5
315      Added the *copy_function* keyword argument.
316
317.. function:: disk_usage(path)
318
319   Return disk usage statistics about the given path as a :term:`named tuple`
320   with the attributes *total*, *used* and *free*, which are the amount of
321   total, used and free space, in bytes.
322
323   .. versionadded:: 3.3
324
325   Availability: Unix, Windows.
326
327.. function:: chown(path, user=None, group=None)
328
329   Change owner *user* and/or *group* of the given *path*.
330
331   *user* can be a system user name or a uid; the same applies to *group*. At
332   least one argument is required.
333
334   See also :func:`os.chown`, the underlying function.
335
336   Availability: Unix.
337
338   .. versionadded:: 3.3
339
340
341.. function:: which(cmd, mode=os.F_OK | os.X_OK, path=None)
342
343   Return the path to an executable which would be run if the given *cmd* was
344   called.  If no *cmd* would be called, return ``None``.
345
346   *mode* is a permission mask passed to :func:`os.access`, by default
347   determining if the file exists and executable.
348
349   When no *path* is specified, the results of :func:`os.environ` are used,
350   returning either the "PATH" value or a fallback of :attr:`os.defpath`.
351
352   On Windows, the current directory is always prepended to the *path* whether
353   or not you use the default or provide your own, which is the behavior the
354   command shell uses when finding executables.  Additionally, when finding the
355   *cmd* in the *path*, the ``PATHEXT`` environment variable is checked.  For
356   example, if you call ``shutil.which("python")``, :func:`which` will search
357   ``PATHEXT`` to know that it should look for ``python.exe`` within the *path*
358   directories.  For example, on Windows::
359
360      >>> shutil.which("python")
361      'C:\\Python33\\python.EXE'
362
363   .. versionadded:: 3.3
364
365
366.. exception:: Error
367
368   This exception collects exceptions that are raised during a multi-file
369   operation. For :func:`copytree`, the exception argument is a list of 3-tuples
370   (*srcname*, *dstname*, *exception*).
371
372
373.. _shutil-copytree-example:
374
375copytree example
376~~~~~~~~~~~~~~~~
377
378This example is the implementation of the :func:`copytree` function, described
379above, with the docstring omitted.  It demonstrates many of the other functions
380provided by this module. ::
381
382   def copytree(src, dst, symlinks=False):
383       names = os.listdir(src)
384       os.makedirs(dst)
385       errors = []
386       for name in names:
387           srcname = os.path.join(src, name)
388           dstname = os.path.join(dst, name)
389           try:
390               if symlinks and os.path.islink(srcname):
391                   linkto = os.readlink(srcname)
392                   os.symlink(linkto, dstname)
393               elif os.path.isdir(srcname):
394                   copytree(srcname, dstname, symlinks)
395               else:
396                   copy2(srcname, dstname)
397               # XXX What about devices, sockets etc.?
398           except OSError as why:
399               errors.append((srcname, dstname, str(why)))
400           # catch the Error from the recursive copytree so that we can
401           # continue with other files
402           except Error as err:
403               errors.extend(err.args[0])
404       try:
405           copystat(src, dst)
406       except OSError as why:
407           # can't copy file access times on Windows
408           if why.winerror is None:
409               errors.extend((src, dst, str(why)))
410       if errors:
411           raise Error(errors)
412
413Another example that uses the :func:`ignore_patterns` helper::
414
415   from shutil import copytree, ignore_patterns
416
417   copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))
418
419This will copy everything except ``.pyc`` files and files or directories whose
420name starts with ``tmp``.
421
422Another example that uses the *ignore* argument to add a logging call::
423
424   from shutil import copytree
425   import logging
426
427   def _logpath(path, names):
428       logging.info('Working in %s', path)
429       return []   # nothing will be ignored
430
431   copytree(source, destination, ignore=_logpath)
432
433
434.. _shutil-rmtree-example:
435
436rmtree example
437~~~~~~~~~~~~~~
438
439This example shows how to remove a directory tree on Windows where some
440of the files have their read-only bit set. It uses the onerror callback
441to clear the readonly bit and reattempt the remove. Any subsequent failure
442will propagate. ::
443
444    import os, stat
445    import shutil
446
447    def remove_readonly(func, path, _):
448        "Clear the readonly bit and reattempt the removal"
449        os.chmod(path, stat.S_IWRITE)
450        func(path)
451
452    shutil.rmtree(directory, onerror=remove_readonly)
453
454.. _archiving-operations:
455
456Archiving operations
457--------------------
458
459.. versionadded:: 3.2
460
461.. versionchanged:: 3.5
462    Added support for the *xztar* format.
463
464
465High-level utilities to create and read compressed and archived files are also
466provided.  They rely on the :mod:`zipfile` and :mod:`tarfile` modules.
467
468.. function:: make_archive(base_name, format, [root_dir, [base_dir, [verbose, [dry_run, [owner, [group, [logger]]]]]]])
469
470   Create an archive file (such as zip or tar) and return its name.
471
472   *base_name* is the name of the file to create, including the path, minus
473   any format-specific extension. *format* is the archive format: one of
474   "zip" (if the :mod:`zlib` module is available), "tar", "gztar" (if the
475   :mod:`zlib` module is available), "bztar" (if the :mod:`bz2` module is
476   available), or "xztar" (if the :mod:`lzma` module is available).
477
478   *root_dir* is a directory that will be the root directory of the
479   archive; for example, we typically chdir into *root_dir* before creating the
480   archive.
481
482   *base_dir* is the directory where we start archiving from;
483   i.e. *base_dir* will be the common prefix of all files and
484   directories in the archive.
485
486   *root_dir* and *base_dir* both default to the current directory.
487
488   If *dry_run* is true, no archive is created, but the operations that would be
489   executed are logged to *logger*.
490
491   *owner* and *group* are used when creating a tar archive. By default,
492   uses the current owner and group.
493
494   *logger* must be an object compatible with :pep:`282`, usually an instance of
495   :class:`logging.Logger`.
496
497   The *verbose* argument is unused and deprecated.
498
499
500.. function:: get_archive_formats()
501
502   Return a list of supported formats for archiving.
503   Each element of the returned sequence is a tuple ``(name, description)``.
504
505   By default :mod:`shutil` provides these formats:
506
507   - *zip*: ZIP file (if the :mod:`zlib` module is available).
508   - *tar*: uncompressed tar file.
509   - *gztar*: gzip'ed tar-file (if the :mod:`zlib` module is available).
510   - *bztar*: bzip2'ed tar-file (if the :mod:`bz2` module is available).
511   - *xztar*: xz'ed tar-file (if the :mod:`lzma` module is available).
512
513   You can register new formats or provide your own archiver for any existing
514   formats, by using :func:`register_archive_format`.
515
516
517.. function:: register_archive_format(name, function, [extra_args, [description]])
518
519   Register an archiver for the format *name*.
520
521   *function* is the callable that will be used to unpack archives. The callable
522   will receive the *base_name* of the file to create, followed by the
523   *base_dir* (which defaults to :data:`os.curdir`) to start archiving from.
524   Further arguments are passed as keyword arguments: *owner*, *group*,
525   *dry_run* and *logger* (as passed in :func:`make_archive`).
526
527   If given, *extra_args* is a sequence of ``(name, value)`` pairs that will be
528   used as extra keywords arguments when the archiver callable is used.
529
530   *description* is used by :func:`get_archive_formats` which returns the
531   list of archivers.  Defaults to an empty string.
532
533
534.. function:: unregister_archive_format(name)
535
536   Remove the archive format *name* from the list of supported formats.
537
538
539.. function:: unpack_archive(filename[, extract_dir[, format]])
540
541   Unpack an archive. *filename* is the full path of the archive.
542
543   *extract_dir* is the name of the target directory where the archive is
544   unpacked. If not provided, the current working directory is used.
545
546   *format* is the archive format: one of "zip", "tar", "gztar", "bztar", or
547   "xztar".  Or any other format registered with
548   :func:`register_unpack_format`.  If not provided, :func:`unpack_archive`
549   will use the archive file name extension and see if an unpacker was
550   registered for that extension.  In case none is found,
551   a :exc:`ValueError` is raised.
552
553
554.. function:: register_unpack_format(name, extensions, function[, extra_args[, description]])
555
556   Registers an unpack format. *name* is the name of the format and
557   *extensions* is a list of extensions corresponding to the format, like
558   ``.zip`` for Zip files.
559
560   *function* is the callable that will be used to unpack archives. The
561   callable will receive the path of the archive, followed by the directory
562   the archive must be extracted to.
563
564   When provided, *extra_args* is a sequence of ``(name, value)`` tuples that
565   will be passed as keywords arguments to the callable.
566
567   *description* can be provided to describe the format, and will be returned
568   by the :func:`get_unpack_formats` function.
569
570
571.. function:: unregister_unpack_format(name)
572
573   Unregister an unpack format. *name* is the name of the format.
574
575
576.. function:: get_unpack_formats()
577
578   Return a list of all registered formats for unpacking.
579   Each element of the returned sequence is a tuple
580   ``(name, extensions, description)``.
581
582   By default :mod:`shutil` provides these formats:
583
584   - *zip*: ZIP file (unpacking compressed files works only if the corresponding
585     module is available).
586   - *tar*: uncompressed tar file.
587   - *gztar*: gzip'ed tar-file (if the :mod:`zlib` module is available).
588   - *bztar*: bzip2'ed tar-file (if the :mod:`bz2` module is available).
589   - *xztar*: xz'ed tar-file (if the :mod:`lzma` module is available).
590
591   You can register new formats or provide your own unpacker for any existing
592   formats, by using :func:`register_unpack_format`.
593
594
595.. _shutil-archiving-example:
596
597Archiving example
598~~~~~~~~~~~~~~~~~
599
600In this example, we create a gzip'ed tar-file archive containing all files
601found in the :file:`.ssh` directory of the user::
602
603    >>> from shutil import make_archive
604    >>> import os
605    >>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
606    >>> root_dir = os.path.expanduser(os.path.join('~', '.ssh'))
607    >>> make_archive(archive_name, 'gztar', root_dir)
608    '/Users/tarek/myarchive.tar.gz'
609
610The resulting archive contains:
611
612.. code-block:: shell-session
613
614    $ tar -tzvf /Users/tarek/myarchive.tar.gz
615    drwx------ tarek/staff       0 2010-02-01 16:23:40 ./
616    -rw-r--r-- tarek/staff     609 2008-06-09 13:26:54 ./authorized_keys
617    -rwxr-xr-x tarek/staff      65 2008-06-09 13:26:54 ./config
618    -rwx------ tarek/staff     668 2008-06-09 13:26:54 ./id_dsa
619    -rwxr-xr-x tarek/staff     609 2008-06-09 13:26:54 ./id_dsa.pub
620    -rw------- tarek/staff    1675 2008-06-09 13:26:54 ./id_rsa
621    -rw-r--r-- tarek/staff     397 2008-06-09 13:26:54 ./id_rsa.pub
622    -rw-r--r-- tarek/staff   37192 2010-02-06 18:23:10 ./known_hosts
623
624
625Querying the size of the output terminal
626----------------------------------------
627
628.. function:: get_terminal_size(fallback=(columns, lines))
629
630   Get the size of the terminal window.
631
632   For each of the two dimensions, the environment variable, ``COLUMNS``
633   and ``LINES`` respectively, is checked. If the variable is defined and
634   the value is a positive integer, it is used.
635
636   When ``COLUMNS`` or ``LINES`` is not defined, which is the common case,
637   the terminal connected to :data:`sys.__stdout__` is queried
638   by invoking :func:`os.get_terminal_size`.
639
640   If the terminal size cannot be successfully queried, either because
641   the system doesn't support querying, or because we are not
642   connected to a terminal, the value given in ``fallback`` parameter
643   is used. ``fallback`` defaults to ``(80, 24)`` which is the default
644   size used by many terminal emulators.
645
646   The value returned is a named tuple of type :class:`os.terminal_size`.
647
648   See also: The Single UNIX Specification, Version 2,
649   `Other Environment Variables`_.
650
651   .. versionadded:: 3.3
652
653.. _`Other Environment Variables`:
654   http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003
655
656