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.