File management

The various graphical environments have a file browser for displaying and manipulating your files. GNOME has Nautilus, Xfce has Thunar, Windows has Explorer.

However, even if you have a graphical desktop available, it can be useful to learn how to manage your files from the command line, since:

  1. You can use your knowledge of these shell commands to write scripts to automate frequent tasks.
  2. If you're quick on the keyboard, it is faster than the GUI tools.
  3. You may not have a graphical environment available, such as administrating a remote server, your graphical environment is broken and you need to fix it, or even your operating system won't boot further than your initramfs, so you're stuck in the rescue shell.

unlink, rmdir and rm

unlink(1) and rm(1) are used for removing files, rm(1) and rmdir(1) are used for removing directories.

The reason for this split is that rmdir(1) and unlink(1) map to the underlying system calls: rmdir(2) and unlink(2), while rm(1) has extra features, such as recursive deletion with rm -rf.

All of these can be given multiple files or directories to remove on the command line.

link and ln

File-systems can contain links to files, so the same file can be referred to by different names.

link(1) creates what is called a hard-link, where two file names refer to the same file, and writes to one alter the other.

ln(1) can also do this, but allows extra options, such as -f to remove the target if it already exists, and -s, which creates a symbolic link, rather than a hard link.

cp, install and mv

cp(1) and install(1) copy files to another location. mv(1) will remove the source file after it has been copied.

install(1) differs from cp(1) by defaulting to creating files with the executable bit set, and can take -m as an option to set the file mode while copying.

cp(1) is the standard tool for copying files. It can take -r to copy a whole directory tree, or -l to create a hardlink. They can be combined to create a quick copy of a whole directory tree.

mv(1) exists to paper over the difference between renaming a file on one file system, which is a quick operation with one invocation of the rename(2) system call, or moving a file to another file system, which requires copying the file to the destination, then removing it at the source.

cp(1) and mv(1) will be the most commonly used, as install(1), is as it name implies, is involved in installing software.

install(1) does have special uses for testing and providing instructions that can be pasted into a terminal, as you can create a file, initialize its contents, then set its permissions all in one command.

$ install -D -m 755 /dev/stdin /tmp/yakking/test-script.sh <<'EOF'
#!/bin/sh
echo "Hello World!"
EOF
$ /tmp/yakking/test-script.sh
Hello World!

Directory management

mkdir(1), as the name implies after adding more letters, makes directories.

Unadorned, mkdir(1) is a thin wrapper over the mkdir(2) system call, however the shell command will also accept a -p parameter, which will create all leading directories up to the specified directory too, allowing a nested directory tree to be created in one command.

$ mkdir -p /tmp/parent/directory/leaf
$ cd /tmp/parent/directory
$ ls
leaf

rmdir(1) likewise removes a directory. It will only remove a directory if it is empty. For directories that are not empty, use rm -r.

mktemp(1) creates a temporary file for you and prints to stdout where it created it. This is mostly useful for scripts.

$ tf="$(mktemp)"
$ echo "Hello World" >"$tf"
$ cat "$tf"
Hello World
$ rm "$tf"

mktemp -d creates a temporary directory. This is handy for creating temporary mount points, or just if you need a bunch of temporary files.

$ td="$(mktemp -d)"
$ echo Hello >"$td/hello"
$ echo World >"$td/world"
$ cat "$td/hello" "$td/world"
Hello World
$ unlink "$td"/*
$ rmdir "$td"

Metadata alteration

Permissions were briefly mentioned when describing install(1). chmod(1) does the same thing as the -m flag, but allows for the symbolic [ugo][+-=][rwx] form, as described in a previous article.

The u in the symbolic mode corresponds to the user that owns the file, and the g for the group. chown(1) and chgrp(1) may be used to change these fields respectively.

touch(1) may be used to update the modification and last-read times, called mtime and atime respectively. -d $TIME sets the time to update the file to. If it is not specified, the current time is used.

File creation and resising

touch(1) is for updating the access times of a file, but it is most commonly used for creating files, as if the file specified does not exist, it is created.

truncate(1) and fallocate(1) perform a similar purpose, ensuring a file is of a certain size. The difference is that fallocate(1) is a thin wrapper over the fallocate(2) or posix_fallocate(3) system calls, which may fail on some file systems, while truncate(1) works more reliably.

The size to set a file to with truncate(1) is specified with -s, and its argument, if prefixed with a + or a -, will instead grow or shring the file by the specified number of bytes.

fallocate(1) is instead specified with o to specify where the file begins, and -l to specify how long the file should be. It will shrink the file if -l is smaller than the file and -n is not specified.

truncate(1) is useful for resising disk images.

$ truncate -s +10GB rootfs.img