Classic Shell Scripting - Arnold Robbins [146]
Show the real filename
0000000 o n e nl t w o nl
157 156 145 012 164 167 157 012
0000010
The octal dump utility, od, reveals the true filename: the first reported newline is part of the name, and the second one ends the output line. A program downstream sees two apparently separate names; we show later in Section 10.4.3 how to deal with such aberrations.
Unlike echo, ls requires that its file arguments exist and complains if they do not:
$ ls this-file-does-not-exist
Try to list a nonexistent file
ls: this-file-does-not-exist: No such file or directory
$ echo $?
Show the ls exit code
1
Without an argument, echo displays only an empty line, but ls instead lists the contents of the current directory. We can demonstrate this behavior by first making a directory with three empty files:
$ mkdir sample
Make a new directory
$ cd sample
Change directory to it
$ touch one two three
Create empty files
and then applying echo and ls to its contents:
$ echo *
Echo matching files
one three two
$ ls *
List matching files
one three two
$ echo
Echo without arguments
This output line is empty
$ ls
List current directory
one three two
Filenames that begin with a dot are hidden from normal shell pattern matching. We can see how such files are handled differently by creating a subdirectory with three hidden files:
$ mkdir hidden
Make a new directory
$ cd hidden
Change directory to it
$ touch .uno .dos .tres
Create three hidden empty files
and then attempting to display its contents:
$ echo *
Echo matching files
* Nothing matched
$ ls
List nonhidden files
This output line is empty
$ ls *
List matching files
ls: *: No such file or directory
When no files match a pattern, the shell leaves the pattern as the argument: here, echo saw an asterisk and printed it, whereas ls tried to find a file named * and reported its failure to do so.
If we now supply a pattern that matches the leading dot, we can see further differences:
$ echo .*
Echo hidden files
. .. .dos .tres .uno
$ ls .*
List hidden files
.dos .tres .uno
.:
..:
hidden one three two
Unix directories always contain the special entries .. (parent directory) and . (current directory), and the shell passed all of the matches to both programs. echo merely reports them, but ls does something more: when a command-line argument is a directory, it lists the contents of that directory. In our example, the listing therefore includes the contents of the parent directory.
You can print information about a directory itself, instead of its contents, with the -d option:
$ ls -d .*
List hidden files, but without directory contents
. .. .dos .tres .uno
$ ls -d ../*
List parent files, but without directory contents
../hidden ../one ../three ../two
Because it is usually not of interest to list the parent directory, ls provides the -a option to list all files in the current directory, including hidden ones:
$ ls -a
List all files, including hidden ones
. .. .dos .tres .uno
The contents of the parent directory were not listed here because there was no argument that named it.
Long File Listings
Because ls knows that its arguments are files, it can report further details about them—notably, some of the filesystem metadata. This is normally done with the -l (lowercase L) option:
$ ls -l /bin/*sh
List shells in /bin
-rwxr-xr-x 1 root root 110048 Jul 17 2002 /bin/ash
-rwxr-xr-x 1 root root 626124 Apr 9 2003 /bin/bash
lrwxrwxrwx 1 root root 3 May 11 2003 /bin/bsh -> ash
lrwxrwxrwx 1 root root 4 May 11 2003 /bin/csh -> tcsh
-rwxr-xr-x 1 root root 206642 Jun 28 2002 /bin/ksh
lrwxrwxrwx 1 root root 4 Aug 1 2003 /bin/sh -> bash
-rwxr-xr-x 1 root root 365432 Aug 8 2002 /bin/tcsh
-rwxr-xr-x 2 root root 463680 Jun 28 2002 /bin/zsh
While this output form is common, additional command-line options can modify its appearance somewhat.
The first character on each line describes the filetype: - for ordinary files, d for directories, l for symbolic links, and so on.
The next nine characters report