=============== Directory Tools =============== .. default-domain:: bash .. file:: dir_tools.bsh Tools that deal with directories and paths, including making temporary file paths. .. function:: parent_find_files :Arguments: ``$1``... - The names of the files being searched for :Return Value: file_matches - array containing matches Find files by searching up the parent tree Searches for files to use. It starts by checking the current directory, and goes up. Just like git searches for a .git directory .. var:: _VSI_TEMP_PATHS .. note:: Do **NOT** mess with this variable. It is used to force recursive remove directories, and any mishaps could result in serious injury to computer, and you, depending on how upset you get by losing your computer. .. function:: make_temp_path :Arguments: ``$1`` - Name of variable where temporary path will be stored [``$2``...] - Optionally add additional arguments to ``mktemp`` calls. The most useful thing to add would be ``-t``, as this is in all the OSes. ``-d`` is often used to make a directory :Parameters: ``DIR_TOOLS_KEEP_TEMP_PATHS`` - Set to keep the temporary paths instead of deleting them (typically for debugging). This can be used in two difference ways. 1) It can be set on each call to :func:`make_temp_path` and only affects that one call. 2) It can also be set globally so that when bash exits, none of the paths will be removed. Default: unset. :Output: ``$1`` - Name of temporary path Create self cleaning temp directories .. rubric:: Usage Use this to create a self deleting temp file/directory. If you do not want to have it self delete, just use ``mktemp`` instead. Can be called multiple times .. rubric:: Example .. code-block:: bash make_temp_path temp_dir -d touch "${temp_dir}"/file1 # Do NOT t="$(make_temp_path temp_dir -d; echo "${temp_dir}")" # or ( make_temp_path temp_dir -d touch "${temp_dir}"/file2 ) # The temp_dir is deleted here cat "${temp_dir}"/file2 # Fails # As these will create and delete the temp dir within the subcommand, by design # This is good, as the temp files will be cleaned up sooner ( make_temp_path temp_dir -d touch "${temp_dir}"/file2 cat "${temp_dir}"/file2 # Success! ) # The temp_dir is deleted here .. note:: This uses the EXIT, INT, and TERM traps. If you use these too, your traps will be automatically chained using :func:`signal_tools.bsh trap_chain`. .. function:: mktemp_compat OS-compatible version of mktemp -p :Arguments: ``$1`` - The location in which to make the temporary directory :Output: *stdout* - The path, ${1}/{a_temp_dir}, to the temporary directory Make a temporary directory in a specific location. This emulates the ``mktemp -p DIR`` behavior for OS's that don't support it (macOS) .. function:: normpath :Arguments: * ``$1`` - path :Output: *stdout* - Normalized path Prints out a normalized version of the path. With .., //, and ./ simplified out, and removes trailing / Unlike :file:`real_path`, this works on non-existing path, but is not as reliable as :file:`real_path` .. function:: basenames :Arguments: * ``$1`` - Number of levels to keep * ``$2`` - path :Output: *stdout* - base name up to ``$1`` levels deep Multiple level version of basename .. note:: ``basenames 2 test`` will result in ``./test`` as the implied dirname is ``.`` .. function:: is_dir_empty Checks to see if there is any files or directories in a given directory, other than ``.`` and ``..``. :Arguments: ``$1`` - The directory to search, must have permissions, or else it may give false results :Return Value: * ``0`` - Empty * ``1`` - Not empty :Uses: ``find`` to search the directory Searches a directory and stops as soon as something is found. You can write your own version of this to modify the conditions the ``find`` use. Other versions include ``find "${1}" -type f -printf '1\n' -quit`` which requires that a file specifically (not a directory) be in the tree somewhere. Add ``-maxdepth 1`` for saying a file must be in the initial directory, not the entire tree. .. function:: get_mktemp_dir Get the default temp dir that mktemp uses :Output: **stdout** - The temp dir, may need :func:`real_path real_path` run on it to dereference symlinks .. function:: common_prefix Return the longest prefix of all list elements. Based on python's ``os.path.commonprefix`` :Arguments: - ``$1`` - A path - ``$2`` - Another path :Output: **stdout** - The longest common prefix .. note:: This function may return invalid paths because it works a character at a time. .. function:: relative_path Return a relative filepath to path from the start directory. :Arguments: - ``$1`` - The file path - ``$2`` - The start path :Output: **stdout** - The relative path This is a path computation; the filesystem is not accessed to confirm the existence or nature of path or start. Based on python's os.path.relpath .. function:: strip_copy :Arguments: * ``$1`` - The source directory * ``$2`` - The destination directory * ``$3`` - Strip this many leading components from file names on ``cp`` Replicates the behavior of ``tar --strip-components``, but when applied to a ``cp`` scenario. .. note:: ``cp`` will process files in a different order than ``tar --strip-components``. In the case where there are multiple files with the same name at a stripped depth, the file may be overwritten in a different order than ``tar --strip-components`` would have. While ``tar`` keeps the first one in the archive order, ``cp`` will keep the last one in ``cp`` order. Consequently, the order is not guaranteed.