# std/os

Theme:

- Manual
- Standard library
- Index
- Compiler docs
- Fusion docs
- devel, stable

Search:
Source Edit

This module contains basic operating system facilities like retrieving environment variables, working with directories, running shell commands, etc.

Example:

    import std/os
    let myFile = "/path/to/my/file.nim"
    assert splitPath(myFile) == (head: "/path/to/my", tail: "file.nim")
    when defined(posix):
      assert parentDir(myFile) == "/path/to/my"
    assert splitFile(myFile) == (dir: "/path/to/my", name: "file", ext: ".nim")
    assert myFile.changeFileExt("c") == "/path/to/my/file.c"

See also:

- paths and files modules for high-level file manipulation
- osproc module for process communication beyond execShellCmd proc
- uri module
- distros module
- dynlib module
- streams module

# Imports

ospaths2, osfiles, osdirs, ossymlinks, osappdirs, oscommon, since, cmdline, strutils, pathnorm, syncio, assertions, widestrs, posix, times, oserrors, envvars, osseps

# Types

    DeviceId = Dev

  Source Edit

    FileId = Ino

  Source Edit

    FileInfo = object
      id*: tuple[device: DeviceId, file: FileId] ## Device and file id.
      kind*: PathComponent       ## Kind of file object - directory, symlink, etc.
      size*: BiggestInt          ## Size of file.
      permissions*: set[FilePermission] ## File permissions
      linkCount*: BiggestInt     ## Number of hard links the file object has.
      lastAccessTime*: times.Time ## Time file was last accessed.
      lastWriteTime*: times.Time ## Time file was last modified/written to.
      creationTime*: times.Time  ## Time file was created. Not supported on all systems!
      blockSize*: int            ## Preferred I/O block size for this object.
                                 ## In some filesystems, this may vary from file to file.
      isSpecial*: bool           ## Is file special? (on Unix some "files"
                                 ## can be special=non-regular like FIFOs,
                                 ## devices); for directories `isSpecial`
                                 ## is always `false`, for symlinks it is
                                 ## the same as for the link's target.

  Contains information associated with a file object.

  See also:

  - getFileInfo(handle) proc
  - getFileInfo(file) proc
  - getFileInfo(path, followSymlink) proc
  Source Edit

# Consts

    ExeExts = [""]

  Platform specific file extension for executables. On Windows `["exe", "cmd", "bat"]`, on Posix `[""]`. Source Edit

    invalidFilenameChars = {'/', '\\', ':', '*', '?', '\"', '<', '>', '|', '^',
                            '\x00'}

  Characters that may produce invalid filenames across Linux, Windows and Mac. You can check if your filename contains any of these chars and strip them for safety. Mac bans `':'`, Linux bans `'/'`, Windows bans all others. Source Edit

    invalidFilenames = ["CON", "PRN", "AUX", "NUL", "COM0", "COM1", "COM2", "COM3",
                        "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT0",
                        "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7",
                        "LPT8", "LPT9"]

  Filenames that may be invalid across Linux, Windows, Mac, etc. You can check if your filename match these and rename it for safety (Currently all invalid filenames are from Windows only). Source Edit

# Procs

    proc createHardlink(src, dest: string) {....raises: [OSError], tags: [],
        forbids: [].}

  Create a hard link at `dest` which points to the item specified by `src`.
  Warning: Some OS's restrict the creation of hard links to root users (administrators).

  See also:

  - symlinks: createSymlink proc
  Source Edit

    proc exclFilePermissions(filename: string; permissions: set[FilePermission]) {.
        ...gcsafe, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect],
        raises: [OSError], forbids: [].}

  A convenience proc for:

      setFilePermissions(filename, getFilePermissions(filename)-permissions)

  Source Edit

    proc execShellCmd(command: string): int {....gcsafe, extern: "nos$1",
        tags: [ExecIOEffect], raises: [], forbids: [].}

  Executes a shell command.

  Command has the form 'program args' where args are the command line arguments given to program. The proc returns the error code of the shell when it has finished (zero if there is no error). The proc does not return until the process has finished.

  To execute a program without having a shell involved, use osproc.execProcess proc.

  Examples:

      discard execShellCmd("ls -la")

  Source Edit

    proc exitStatusLikeShell(status: cint): cint {....raises: [], tags: [], forbids: [].}

  Converts exit code from `c_system` into a shell exit code. Source Edit

    proc expandFilename(filename: string): string {....gcsafe, extern: "nos$1",
        tags: [ReadDirEffect], raises: [OSError], forbids: [].}

  Returns the full (absolute) path of an existing file `filename`.

  Raises `OSError` in case of an error. Follows symlinks.

  Source Edit

    proc expandTilde(path: string): string {....tags: [ReadEnvEffect, ReadIOEffect],
        raises: [], forbids: [].}

  Expands `~` or a path starting with `~/` to a full path, replacing `~` with appdirs: getHomeDir() (otherwise returns `path` unmodified).

  Windows: this is still supported despite the Windows platform not having this convention; also, both `~/` and `~\` are handled.

  See also:

  - appdirs: getHomeDir proc
  - appdirs: getConfigDir proc
  - appdirs: getTempDir proc
  - ospaths2: getCurrentDir proc
  - dirs: setCurrentDir proc

  Example:

      assert expandTilde("~" / "appname.cfg") == getHomeDir() / "appname.cfg"
      assert expandTilde("~/foo/bar") == getHomeDir() / "foo/bar"
      assert expandTilde("/foo/bar") == "/foo/bar"

  Source Edit

    proc fileNewer(a, b: string): bool {....gcsafe, extern: "nos$1", raises: [OSError],
                                         tags: [], forbids: [].}

  Returns true if the file `a` is newer than file `b`, i.e. if `a`'s modification time is later than `b`'s.

  See also:

  - getLastModificationTime proc
  - getLastAccessTime proc
  - getCreationTime proc
  Source Edit

    proc findExe(exe: string; followSymlinks: bool = true;
                 extensions: openArray[string] = ExeExts): string {.
        ...tags: [ReadDirEffect, ReadEnvEffect, ReadIOEffect], raises: [OSError],
        forbids: [].}

  Searches for `exe` in the current working directory and then in directories listed in the `PATH` environment variable.

  Returns `""` if the `exe` cannot be found. `exe` is added the ExeExts file extensions if it has none.

  If the system supports symlinks it also resolves them until it meets the actual file. This behavior can be disabled if desired by setting `followSymlinks = false`.

  Source Edit

    proc getAppDir(): string {....gcsafe, extern: "nos$1", tags: [ReadIOEffect],
                               raises: [], forbids: [].}

  Returns the directory of the application's executable.

  See also:

  - getAppFilename proc
  Source Edit

    proc getAppFilename(): string {....gcsafe, extern: "nos$1", tags: [ReadIOEffect],
                                    raises: [], forbids: [].}

  Returns the filename of the application's executable. This proc will resolve symlinks.

  Returns empty string when name is unavailable

  See also:

  - getAppDir proc
  - getCurrentCompilerExe proc
  Source Edit

    proc getCreationTime(file: string): times.Time {....gcsafe, extern: "nos$1",
        raises: [OSError], tags: [], forbids: [].}

  Returns the `file`'s creation time.

  Note: Under POSIX OS's, the returned time may actually be the time at which the file's attribute's were last modified. See here for details.

  See also:

  - getLastModificationTime proc
  - getLastAccessTime proc
  - fileNewer proc
  Source Edit

    proc getCurrentCompilerExe(): string {.compileTime, ...raises: [], tags: [],
                                           forbids: [].}

  This is getAppFilename() at compile time.

  Can be used to retrieve the currently executing Nim compiler from a Nim or nimscript program, or the nimble binary inside a nimble program (likewise with other binaries built from compiler API).

  Source Edit

    proc getCurrentProcessId(): int {....raises: [], tags: [], forbids: [].}

  Return current process ID.

  See also:

  - osproc.processID(p: Process)
  Source Edit

    proc getFileInfo(file: File): FileInfo {....raises: [IOError, OSError], tags: [],
        forbids: [].}

  Retrieves file information for the file object.

  See also:

  - getFileInfo(handle) proc
  - getFileInfo(path, followSymlink) proc
  Source Edit

    proc getFileInfo(handle: FileHandle): FileInfo {....raises: [OSError], tags: [],
        forbids: [].}

  Retrieves file information for the file object represented by the given handle.

  If the information cannot be retrieved, such as when the file handle is invalid, `OSError` is raised.

  See also:

  - getFileInfo(file) proc
  - getFileInfo(path, followSymlink) proc
  Source Edit

    proc getFileInfo(path: string; followSymlink = true): FileInfo {.
        ...raises: [OSError], tags: [], forbids: [].}

  Retrieves file information for the file object pointed to by `path`.

  Due to intrinsic differences between operating systems, the information contained by the returned FileInfo object will be slightly different across platforms, and in some cases, incomplete or inaccurate.

  When `followSymlink` is true (default), symlinks are followed and the information retrieved is information related to the symlink's target. Otherwise, information on the symlink itself is retrieved (however, field `isSpecial` is still determined from the target on Unix).

  If the information cannot be retrieved, such as when the path doesn't exist, or when permission restrictions prevent the program from retrieving file information, `OSError` is raised.

  See also:

  - getFileInfo(handle) proc
  - getFileInfo(file) proc
  Source Edit

    proc getFileSize(file: string): BiggestInt {....gcsafe, extern: "nos$1",
        tags: [ReadIOEffect], raises: [OSError], forbids: [].}

  Returns the file size of `file` (in bytes). `OSError` is raised in case of an error. Source Edit

    proc getLastAccessTime(file: string): times.Time {....gcsafe, extern: "nos$1",
        raises: [OSError], tags: [], forbids: [].}

  Returns the `file`'s last read or write access time.

  See also:

  - getLastModificationTime proc
  - getCreationTime proc
  - fileNewer proc
  Source Edit

    proc getLastModificationTime(file: string): times.Time {....gcsafe,
        extern: "nos$1", raises: [OSError], tags: [], forbids: [].}

  Returns the `file`'s last modification time.

  See also:

  - getLastAccessTime proc
  - getCreationTime proc
  - fileNewer proc
  Source Edit

    proc inclFilePermissions(filename: string; permissions: set[FilePermission]) {.
        ...gcsafe, extern: "nos$1", tags: [ReadDirEffect, WriteDirEffect],
        raises: [OSError], forbids: [].}

  A convenience proc for:

      setFilePermissions(filename, getFilePermissions(filename)+permissions)

  Source Edit

    proc isAdmin(): bool {....raises: [], tags: [], forbids: [].}

  Returns whether the caller's process is a member of the Administrators local group (on Windows) or a root (on POSIX), via `geteuid() == 0`. Source Edit

    proc isHidden(path: string): bool {....raises: [], tags: [], forbids: [].}

  Determines whether `path` is hidden or not, using this reference.

  On Windows: returns true if it exists and its "hidden" attribute is set.

  On posix: returns true if `lastPathPart(path)` starts with `.` and is not `.` or `..`.

  Note: paths are not normalized to determine `isHidden`.

  Example:

      when defined(posix):
        assert ".foo".isHidden
        assert not ".foo/bar".isHidden
        assert not ".".isHidden
        assert not "..".isHidden
        assert not "".isHidden
        assert ".foo/".isHidden

  Source Edit

    func isValidFilename(filename: string; maxLen = 259.Positive): bool {.
        ...raises: [], tags: [], forbids: [].}

  Returns `true` if `filename` is valid for crossplatform use.

  This is useful if you want to copy or save files across Windows, Linux, Mac, etc. It uses `invalidFilenameChars`, `invalidFilenames` and `maxLen` to verify the specified `filename`.

  See also:

  - https://docs.microsoft.com/en-us/dotnet/api/system.io.pathtoolongexception
  - https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
  - https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
  Warning: This only checks filenames, not whole paths (because basically you can mount anything as a path on Linux).

  Example:

      assert not isValidFilename(" foo")     # Leading white space
      assert not isValidFilename("foo ")     # Trailing white space
      assert not isValidFilename("foo.")     # Ends with dot
      assert not isValidFilename("con.txt")  # "CON" is invalid (Windows)
      assert not isValidFilename("OwO:UwU")  # ":" is invalid (Mac)
      assert not isValidFilename("aux.bat")  # "AUX" is invalid (Windows)
      assert not isValidFilename("")         # Empty string
      assert not isValidFilename("foo/")     # Filename is empty

  Source Edit

    proc quoteShell(s: string): string {.noSideEffect, ...gcsafe, extern: "nosp$1",
                                         raises: [], tags: [], forbids: [].}

  Quote `s`, so it can be safely passed to shell.

  When on Windows, it calls quoteShellWindows proc. Otherwise, calls quoteShellPosix proc.

  Source Edit

    proc quoteShellCommand(args: openArray[string]): string {....raises: [], tags: [],
        forbids: [].}

  Concatenates and quotes shell arguments `args`.

  Example:

      when defined(posix):
        assert quoteShellCommand(["aaa", "", "c d"]) == "aaa '' 'c d'"
      when defined(windows):
        assert quoteShellCommand(["aaa", "", "c d"]) == "aaa \"\" \"c d\""

  Source Edit

    proc quoteShellPosix(s: string): string {.noSideEffect, ...gcsafe,
        extern: "nosp$1", raises: [], tags: [], forbids: [].}

  Quote `s`, so it can be safely passed to POSIX shell. Source Edit

    proc quoteShellWindows(s: string): string {.noSideEffect, ...gcsafe,
        extern: "nosp$1", raises: [], tags: [], forbids: [].}

  Quote `s`, so it can be safely passed to Windows API.

  Based on Python's `subprocess.list2cmdline`. See this link for more details.

  Source Edit

    proc sameFileContent(path1, path2: string): bool {....gcsafe, extern: "nos$1",
        tags: [ReadIOEffect], raises: [IOError, OSError], forbids: [].}

  Returns true if both pathname arguments refer to files with identical binary content.

  See also:

  - ospaths2: sameFile proc
  Source Edit

    proc setLastModificationTime(file: string; t: times.Time) {....raises: [OSError],
        tags: [], forbids: [].}

  Sets the `file`'s last modification time. `OSError` is raised in case of an error. Source Edit

    proc sleep(milsecs: int) {....gcsafe, extern: "nos$1", tags: [TimeEffect],
                               raises: [], forbids: [].}

  Sleeps `milsecs` milliseconds. Source Edit

# Templates

    template existsDir(args: varargs[untyped]): untyped {.
        ...deprecated: "use dirExists".}

  Deprecated: use dirExists
  Source Edit

    template existsFile(args: varargs[untyped]): untyped {.
        ...deprecated: "use fileExists".}

  Deprecated: use fileExists
  Source Edit

# Exports

extractFilename, DynlibFormat, CurDir, ReadDirEffect, /, AltSep, normalizePathEnd, searchExtPos, splitFile, isRootDir, parentDir, DirSep, unixToNativePath, PathSep, tailDir, parentDirs, relativePath, doslikeFileSystem, FileSystemCaseSensitive, lastPathPart, ExtSep, isRelativeTo, getCurrentDir, ParDir, normalizeExe, joinPath, absolutePath, ScriptExt, isAbsolute, joinPath, normalizePath, changeFileExt, cmpPaths, splitPath, sameFile, /../, normalizePathEnd, WriteDirEffect, ExeExt, normalizedPath, addFileExt, removeFile, moveFile, tryRemoveFile, copyFile, setFilePermissions, fileExists, CopyFlag, FilePermission, copyFileWithPermissions, getFilePermissions, copyFileToDir, walkDirRec, removeDir, moveDir, walkPattern, walkFiles, copyDir, walkDirs, createDir, dirExists, PathComponent, walkDir, existsOrCreateDir, setCurrentDir, copyDirWithPermissions, expandSymlink, createSymlink, symlinkExists, getDataDir, getTempDir, getConfigDir, getHomeDir, getCacheDir, getCacheDir, paramStr, commandLineParams, parseCmdLine, paramCount, $, ==, osErrorMsg, newOSError, osLastError, OSErrorCode, raiseOSError, getEnv, ReadEnvEffect, WriteEnvEffect, existsEnv, delEnv, putEnv, envPairs, DirSep, CurDir, ExeExt, ParDir, PathSep, ScriptExt, AltSep, DynlibFormat, ExtSep, doslikeFileSystem, FileSystemCaseSensitive