You are currently viewing Basic Linux File Command Options

Photo from Unsplash by mvdheuvel

Now that some basic commands have been covered, we can dive into some of their common options.  Options are a type of argument you can add to a command that changes the behavior of that command.  This could be a wide range of things: altering the output, changing which files you’d like to use, executing a dry run, and so on.

Long ago, I would check manual pages for commands and feel overwhelmed with the innumerable options available for each command.  There’s already a lot of Linux commands, how was I supposed to remember all these options for them as well?  The answer: you don’t.

I don’t memorize all the command options just like I don’t memorize all commands – I simply look them up when needed. Similar to the commands themselves, I only commit frequently used options to memory.  After scanning and trying these options for yourself, you’ll undoubtedly find some options are more worthwhile than others; as a result, you’ll use those options more and, eventually, they will become second nature.

OVERVIEW

In this article, we’ll cover several options for common commands.  This will enable us to tweak the behavior of the commands we run.

NOTE: System Specifics
All the following commands were tested on a CentOS 7 VM. If you are using a different system, your results may vary.

Outline

  • Viewing Files and Folders
    • pwd
    • ls
    • cd
    • cat
    • less
    • head
    • tail
  • Editing Files and Folders
    • touch
    • mkdir
    • mv
    • cp
    • rm

Prerequisites

VIEWING FILES AND FOLDERS

The following sections will review common options for frequently used commands.

pwd

  • Option(s): -P, --physical
  • Manual page description: “avoid all symlinks”.

NOTE: Symlinks
A symlink is a file that points to another file, much like a shortcut on Windows systems.

If you are in a directory that is a symlink to another directory, the -P option for the pwd command will output the actual, “physical” location of your present working directory. For example, let’s assume the foo directory is a symlink to the bar directory: foo -> bar. If you are in the foo directory, executing pwd will display foo while pwd -P will show bar instead:

[penguin@centos7 foo]$ pwd
/home/penguin/foo
[penguin@centos7 foo]$ pwd -P
/home/penguin/bar

This also works if there are multiple symlinks; for example, assume spam links to foo, which links to bar: “spam -> foo -> bar”. Executing pwd -P from the spam folder will display bar:

[penguin@centos7 spam]$ pwd
/home/penguin/spam
[penguin@centos7 spam]$ pwd -P
/home/penguin/bar

ls

  • Option(s): -l
  • Manual page description: “use a long listing format”.

To see more details about files and directories, beyond just the file names, use the -l option. This will display the type of file(s), permissions, last modification date, and more. Here, you can see the symlinked directories from the previous section:

[penguin@centos7 ~]$ ls
bar  foo  spam
[penguin@centos7 ~]$ ls -l
total 0
drwxrwxr-x. 4 penguin penguin 89 Oct 27 20:38 bar
lrwxrwxrwx. 1 penguin penguin  3 Nov 21 15:41 foo -> bar
lrwxrwxrwx. 1 penguin penguin  3 Nov 21 15:49 spam -> foo

NOTE: File Types
For each listed file/directory, the first letter indicates the type of file. Here, the d means that bar is a directory and the l means that foo and spam are symlinks.

  • Option(s): -d, --directory
  • Manual page description: “list directories themselves, not their contents”

As the man (manual) page says, the -d option will display the folder name instead of the files inside it:

[penguin@centos7 bar]$ ls AnotherDirectory
eggs.txt  spam.txt
[penguin@centos7 bar]$ ls -d AnotherDirectory
AnotherDirectory
  • Option(s): -h, --human-readable
  • Manual page description: “with -l, print sizes in human readable format”.

When using the -l option, you can see the file sizes (in bytes) just before the date:

[penguin@centos7 bar]$ ls -l
total 17408
drwxrwxr-x. 2 penguin penguin       38 Nov 21 16:10 AnotherDirectory
-rw-r--r--. 1 penguin penguin 11728120 Nov 21 16:29 duplicate.png
drwxrwxr-x. 2 penguin penguin       42 Oct 27 20:25 MyNewFolder
-rw-r--r--. 1 penguin penguin   833161 Nov 21 16:29 picture.png

NOTE: Directory “Size”
The displayed size for the directories is not the accumulated size of all files and folders within that directory.

However, you might prefer to see the equivalent sizes in kilobytes, megabytes, and so on. To do this you’ll add the -h option:

[penguin@centos7 bar]$ ls -lh
total 17M
drwxrwxr-x. 2 penguin penguin   38 Nov 21 16:10 AnotherDirectory
-rw-r--r--. 1 penguin penguin  12M Nov 21 16:29 duplicate.png
drwxrwxr-x. 2 penguin penguin   42 Oct 27 20:25 MyNewFolder
-rw-r--r--. 1 penguin penguin 814K Nov 21 16:29 picture.png

Now, you can see the duplicate.png file in megabytes (M) and the picture.png in kilobytes (K). Keep in mind, you have to use -h with the -l option. You’ll notice no difference when using -h by itself:

[penguin@centos7 bar]$ ls
AnotherDirectory  duplicate.png  MyNewFolder  picture.png
[penguin@centos7 bar]$ ls -h
AnotherDirectory  duplicate.png  MyNewFolder  picture.png

cd

  • Option(s): -

Using a lone dash - with the cd command is a special case that will switch you to your previous directory:

[penguin@centos7 ~]$ pwd
/home/penguin
[penguin@centos7 ~]$ cd foo
[penguin@centos7 foo]$ pwd
/home/penguin/foo
[penguin@centos7 foo]$ cd -
/home/penguin
[penguin@centos7 ~]$ pwd
/home/penguin

NOTE: $OLDPWD Environment Variable
Like the $PWD (Present Working Directory) environment variable, which stores/remembers your CWD, the $OLDPWD (OLD Present Working Directory) environment variable stores/remembers your previous working directory. You can view this variable’s contents with this command: echo $OLDPWD. When using cd -, the - gets automatically replaced with the contents of $OLDPWD.

cat

  • Option(s): -n, --number
  • Manual page description: “number all output lines”.

When displaying a lengthy plaintext file, it can be helpful to know the exact line number for each line. To do this, you can use the -n option:

[penguin@centos7 ~]$ cat -n /etc/crontab
     1  SHELL=/bin/bash
     2  PATH=/sbin:/bin:/usr/sbin:/usr/bin
     3  MAILTO=root
     4
     5  # For details see man 4 crontabs
     6
     7  # Example of job definition:
     8  # .---------------- minute (0 - 59)
     9  # |  .------------- hour (0 - 23)
    10  # |  |  .---------- day of month (1 - 31)
    11  # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    12  # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
    13  # |  |  |  |  |
    14  # *  *  *  *  * user-name  command to be executed
    15
  • Option(s): -b, --number-nonblank
  • Manual page description: “number nonempty output lines, overrides -n”.

Similarly, if you only want to see numbers for lines that aren’t empty, use the -b option:

[penguin@centos7 ~]$ cat -b /etc/crontab
     1  SHELL=/bin/bash
     2  PATH=/sbin:/bin:/usr/sbin:/usr/bin
     3  MAILTO=root

     4  # For details see man 4 crontabs

     5  # Example of job definition:
     6  # .---------------- minute (0 - 59)
     7  # |  .------------- hour (0 - 23)
     8  # |  |  .---------- day of month (1 - 31)
     9  # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    10  # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
    11  # |  |  |  |  |
    12  # *  *  *  *  * user-name  command to be executed

less

  • Option(s): -N, --LINE-NUMBERS
  • Manual page description: “Causes a line number to be displayed at the beginning of each line in the display”.

Equivalent to the previous cat options, if you want to see line numbers and scroll within a plaintext file, use less -N <FileName>:

[penguin@centos7 ~]$ less -N /etc/services

Potential output:

      1 # /etc/services:
      2 # $Id: services,v 1.55 2013/04/14 ovasik Exp $
      3 #
      4 # Network services, Internet style
      5 # IANA services version: last updated 2013-04-10
      6 #
      7 # Note that it is presently the policy of IANA to assign a single well-known
      8 # port number for both TCP and UDP; hence, most entries here have two entries
      9 # even if the protocol doesn't support UDP operations.
     10 # Updated from RFC 1700, ``Assigned Numbers'' (October 1994).  Not all ports
     11 # are included, only the more common ones.
...
  • Option(s): +
  • Manual page description: “…. As a special case, + acts like +g; that is, it starts the display at the specified line number”.

In longer plaintext files, you can jump to a specific line number with the + option:

[penguin@centos7 ~]$ less +11 /etc/services

Potential output:

# are included, only the more common ones.
#
# The latest IANA port assignments can be gotten from
#       http://www.iana.org/assignments/port-numbers
# The Well Known Ports are those from 0 through 1023.
# The Registered Ports are those from 1024 through 49151
# The Dynamic and/or Private Ports are those from 49152 through 65535
#
# Each line describes one service, and is of the form:
#
# service-name  port/protocol  [aliases ...]   [# comment]

...

You can also combine the options:

[penguin@centos7 ~]$ less -N +11 /etc/services

Potential output:

     11 # are included, only the more common ones.
     12 #
     13 # The latest IANA port assignments can be gotten from
     14 #       http://www.iana.org/assignments/port-numbers
     15 # The Well Known Ports are those from 0 through 1023.
     16 # The Registered Ports are those from 1024 through 49151
     17 # The Dynamic and/or Private Ports are those from 49152 through 65535
     18 #
     19 # Each line describes one service, and is of the form:
     20 #
     21 # service-name  port/protocol  [aliases ...]   [# comment]
     22
...

head

  • Option(s): -n, --lines=[-]K
  • Manual page description: “print the first K lines instead of the first 10; with the leading ‘-‘, print all but the last K lines of each file”.

You can specify how many lines you’d like to view from the top of the file with the -n option and a number: head -n <Number> <FileName>. For example, let’s first take a look at the full /etc/crontab file:

[penguin@centos7 etc]$ cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

If you only want to see the first three lines of /etc/crontab, use the -n option:

[penguin@centos7 etc]$ head -n 3 /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

Alternatively, you can use a negative number to see everything except the last “X” lines of a file:

[penguin@centos7 etc]$ head -n -3 /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat

tail

  • Option(s): -n, --lines=K
  • Manual page description: “output the last K lines, instead of the last 10; or use -n +K to output starting with the Kth”.

Similar to the previous head command, you can view the last “X” lines with the -n option: tail -n <Number> <FileName>.

[penguin@centos7 etc]$ tail -n 5 /etc/crontab
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

Conversely, by using a +, you may print onward from a specific line: tail -n +<Number> <FileName>.

[penguin@centos7 etc]$ tail -n +5 /etc/crontab
# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
  • Option(s): -f
  • Manual page description: “output appended data as the file grows”.

For the tail command, -f is one of the most useful options for troubleshooting. With this, you can view a file as it changes because it will “follow” the bottom of a file in real time and continuously display any new lines: tail -f <FileName>.

To test this, execute the following command:

[penguin@centos7 ~]$ echo “” > test.log ;for range in `seq 1 60` ;do date >> test.log ;sleep 1 ;done &

As a background process, this will create a test log file (test.log) in the present working directory and print the date & time into it every second for 60 seconds. Promptly tail that file to see the live changes:

[penguin@centos7 ~]$ tail -f test.log

Press Ctrl + c to exit.

EDITING FILES AND FOLDERS

The following sections continue to expand on options for “edit” type commands.

touch

  • Option(s): -t STAMP
  • Manual page description: “use [[CC]YY]MMDDhhmm[.ss] instead of current time”.

To manually set a file’s timestamp, you can use the -t option with the year, month, day, hour, and minute: touch -t <YYYYMMDDhhmm> <FileName>.

[penguin@centos7 ~]$ ls -l test.log
-rw-rw-r--. 1 penguin penguin 1741 Jan  1  2000 test.log
[penguin@centos7 ~]$ touch -t 201002030405 test.log
[penguin@centos7 ~]$ ls -l test.log
-rw-rw-r--. 1 penguin penguin 1741 Feb  3  2010 test.log
[penguin@centos7 ~]$ touch -t 202007080910 test.log
[penguin@centos7 ~]$ ls -l test.log
-rw-rw-r--. 1 penguin penguin 1741 Jul  8 09:10 test.log

NOTE: Recent Timestamps
When using ls -l to view file timestamps, depending on how old the timestamp is, the year may be displayed instead of the time.

mkdir

  • Option(s): -p, --parents
  • Manual page description: “no error if existing, make parent directories as needed”.

Usually, you can only create directories one level “deep” into the file system. For example, if the foo directory already exists and you want to create the spam folder two levels “underneath” it, you’d have to first create foo/bar, then foo/bar/spam:

[penguin@centos7 ~]$ ls foo/
[penguin@centos7 ~]$ mkdir foo/bar
[penguin@centos7 ~]$ mkdir foo/bar/spam
[penguin@centos7 ~]$ ls foo/
bar
[penguin@centos7 ~]$ ls foo/bar/
spam

However, with the -p option, you can create multiple directories at any depth simultaneously:

[penguin@centos7 ~]$ ls foo/
[penguin@centos7 ~]$ mkdir foo/bar/spam
mkdir: cannot create directory ‘foo/bar/spam’: No such file or directory
[penguin@centos7 ~]$ mkdir -p foo/bar/spam
[penguin@centos7 ~]$ ls foo/
bar
[penguin@centos7 ~]$ ls foo/bar/
spam

mv

  • Option(s): -f, --force
  • Manual page description: “do not prompt before overwriting”.

Depending on file permissions, when moving a file to a place where the same file name already exists, you may be prompted to confirm overwriting the destination file:

[penguin@centos7 ~]$ ls -l
total 0
drwxrwxr-x. 2 penguin penguin 22 Jan 16 17:56 bar
drwxrwxr-x. 2 penguin penguin 22 Jan 16 17:57 foo
[penguin@centos7 ~]$ ls foo/ bar/
bar/:
file.txt

foo/:
file.txt
[penguin@centos7 ~]$ mv foo/file.txt bar/file.txt
mv: try to overwrite ‘bar/file.txt’, overriding mode 0400 (r--------)?

This is usually a good thing but, for instance, if you want to automate a file move that’s expected to overwrite the destination, you could use the -f option, which will skip the prompt:

[penguin@centos7 ~]$ mv -f foo/file.txt bar/file.txt

cp

  • Option(s): -R, -r, --recursive
  • Manual page description: “copy directories recursively”.

If you try to copy a folder directly, you’ll receive an error:

[penguin@centos7 ~]$ ls -l
total 0
drwxrwxr-x. 2 penguin penguin 36 Oct 23 10:53 foo
[penguin@centos7 ~]$ cp foo bar
cp: omitting directory ‘foo’

To copy a directory (and all of its contents) properly, use the -r option to “recurse” through the folder:

[penguin@centos7 ~]$ cp -r foo bar

Here, you can see that both files are copied into the new bar directory as well:

[penguin@centos7 ~]$ ls -l bar/
total 0
-rw-rw-r--. 1 penguin penguin 0 Nov  2 17:15 one.txt
-rw-rw-r--. 1 penguin penguin 0 Nov  2 17:15 two.txt

rm

  • Option(s): -r, -R, --recursive
  • Manual page description: “remove directories and their contents recursively”.

Akin to the recursive option for the cp command, the -r option for rm will delete a directory and everything in it.

  • Option(s): -f, –force
  • Manual page description: “ignore nonexistent files and arguments, never prompt”.

Again, like the mv command, the -f option will omit the confirmation prompt when using rm.

WARNING: rm -rf
Use caution when executing any removal command; yet, be particularly careful with this combination because it can irrevocably delete a lot of data in a short amount of time.

The combination of the rm command with the -r and -f options is simultaneously one of the most useful and most risky commands a Linux admin could execute. It will quickly delete many files and directories without asking you if you’d like to proceed:

[penguin@centos7 ~]$ ls foo/ foo/AnotherDirectory/ foo/AnotherDirectory/
foo/:
AnotherDirectory  duplicate.png  file.txt  MyNewFolder  picture.png

foo/AnotherDirectory/:
eggs.txt  spam.txt

foo/AnotherDirectory/:
eggs.txt  spam.txt
[penguin@centos7 ~]$ rm -rf foo
[penguin@centos7 ~]$ ls foo/ foo/AnotherDirectory/ foo/AnotherDirectory/
ls: cannot access foo/: No such file or directory
ls: cannot access foo/AnotherDirectory/: No such file or directory
ls: cannot access foo/AnotherDirectory/: No such file or directory

CONCLUSION

Now that you know some basic commands and their options, you’re better prepared to view and manipulate files, directories, and their contents.  Just like the commands themselves, it takes time and practice before they become involuntary.  Even now, I frequently use web searches and manual pages to learn and remember new command options.