3.4 Creazione, spostamento ed eliminazione dei file

Introduction

This lesson covers managing files and directories on Linux using command line tools.

A file is a collection of data with a name and set of attributes. If, for example, you were to transfer some photos from your phone to a computer and give them descriptive names, you would now have a bunch of image files on your computer. These files have attributes such as the time the file was last accessed or modified.

A directory is a special kind of file used to organize files. A good way to think of directories is like the file folders used to organize papers in a file cabinet. Unlike paper file folders, you can easily put directories inside of other directories.

The command line is the most effective way to manage files on a Linux system. The shell and command line tools have features that make using the command line faster and easier than a graphical file manager.

In this section you will use the commands lsmvcppwdfindtouchrmrmdirechocat, and mkdir to manage and organize files and directories.

Case Sensitivity

Unlike Microsoft Windows, file and directory names on Linux systems are case sensitive. This means that the names /etc/ and /ETC/ are different directories. Try the following commands:

$ cd /
$ ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr
$ cd ETC
bash: cd: ETC: No such file or directory
$ pwd
/
$ cd etc
$ pwd
/etc

The pwd shows you the directory you are currently in. As you can see, changing to /ETC did not work as there is no such directory. Changing into the directory /etc which exists, did succeed.

Creating Directories

The mkdir command is used to create directories.

Let’s create a new directory within our home directory:

$ cd ~
$ pwd
/home/user
$ ls
Desktop  Documents  Downloads
$ mkdir linux_essentials-2.4
$ ls
Desktop  Documents  Downloads  linux_essentials-2.4
$ cd linux_essentials-2.4
$ pwd
/home/emma/linux_essentials-2.4

For the duration of this lesson, all commands will take place within this directory or in one of its subdirectories.

To easily return to the lesson directory from any other posistion in your file system, you can use the command:

$ cd ~/linux_essentials-2.4

The shell interprets the ~ character as your home directory.

When you’re in the lesson directory, create some more directories which we will use for the exercises. You can add all the directory names, separated by spaces, to mkdir:

$ mkdir creating moving copying/files copying/directories deleting/directories deleting/files globs
mkdir: cannot create directory ‘copying/files’: No such file or directory
mkdir: cannot create directory ‘copying/directories’: No such file or directory
mkdir: cannot create directory ‘deleting/directories’: No such file or directory
mkdir: cannot create directory ‘deleting/files’: No such file or directory
$ ls
creating  globs  moving

Notice the error message and that only movingglobs, and creating were created. The copying and deleting directories don’t exist yet. mkdir, by default, won’t create a directory inside of a directory that does not exist. The -p or --parents option instructs mkdir to create parent directories if they do not exist. Try the same mkdir command with the -p option:

$ mkdir -p creating moving copying/files copying/directories deleting/directories deleting/files globs

Now you don’t get any error messages. Let’s see which directories exist now:

$ find
.
./creating
./moving
./globs
./copying
./copying/files
./copying/directories
./deleting
./deleting/directories
./deleting/files

The find program is usually used to search for files and directories, but without any options, it will show you a listing of all the files, directories, and sub-directories of your current directory.

TipWhen listing the contents of a directory with ls, the -t and -r options are particularly handy. They sort the output by time (-t) and reverse the sorting order (-r). In this case, the newest files will be at the bottom of the output.

Creating Files

Typically, files will be created by the programs that work with the data stored in the files. An empty file can be created using the touch command. If you run touch on an existing file, the file’s contents won’t be changed, but the files modification timestamp will be updated.

Run the following command to create some files for the globbing lesson:

$ touch globs/question1 globs/question2012 globs/question23 globs/question13 globs/question14
$ touch globs/star10 globs/star1100 globs/star2002 globs/star2013

Now let’s verify all files exist in the globs directory:

$ cd globs
$ ls
question1   question14    question23  star1100  star2013
question13  question2012  star10      star2002

Notice how touch created the files? You can view the contents of a text file with the cat command. Try it on one of the files you just created:

$ cat question14

Since touch creates empty files, you should get no output. You can use echo with > to create simple text files. Try it:

$ echo hello > question15
$ cat question15
hello

echo displays text on the command line. The > character instructs the shell to write output of a file to the specified file instead of your terminal. This leads to the output of echohello in this case, being written to the file question15. This isn’t specific to echo, it can be used with any command.

WarningBe careful when using >! If the named file already exists, it will be overwritten!

Renaming Files

Files are moved and renamed with the mv command.

Set your working directory to the moving directory:

$ cd ~/linux_essentials-2.4/moving

Create some files to practice with. By now, you should already be familiar with these commands:

$ touch file1 file22
$ echo file3 > file3
$ echo file4 > file4
$ ls
file1  file22  file3  file4

Suppose file22 is a typo and should be file2. Fix it with the mv command. When renaming a file, the first argument is the current name, the second is the new name:

$ mv file22 file2
$ ls
file1  file2  file3  file4

Be careful with the mv command. If you rename a file to the name of an existing file, it will overwrite it. Let’s test this with file3 and file4:

$ cat file3
file3
$ cat file4
file4
$ mv file4 file3
$ cat file3
file4
$ ls
file1  file2  file3

Notice how the contents of file3 is now file4. Use the -i option to make mv prompt you if you are about to overwrite an existing file. Try it:

$ touch file4 file5
$ mv -i file4 file3
mv: overwrite ‘file3’? y

Moving Files

Files are moved from one directory to another with the mv command.

Create a few directories to move files into:

$ cd ~/linux_essentials-2.4/moving
$ mkdir dir1 dir2
$ ls
dir1  dir2  file1  file2  file3  file5

Move file1 into dir1:

$ mv file1 dir1
$ ls
dir1  dir2  file2  file3  file5
$ ls dir1
file1

Notice how the last argument to mv is the destination directory. Whenever the last argument to mv is a directory, files are moved into it. Multiple files can be specified in a single mv command:

$ mv file2 file3 dir2
$ ls
dir1  dir2  file5
$ ls dir2
file2  file3

It is also possible to use mv to move and rename directories. Rename dir1 to dir3:

$ ls
dir1  dir2  file5
$ ls dir1
file1
$ mv dir1 dir3
$ ls
dir2  dir3  file5
$ ls dir3
file1

Deleting Files and Directories

The rm command can delete files and directories, while the rmdir command can only delete directories. Let’s clean up the moving directory by deleting file5:

$ cd ~/linux_essentials-2.4/moving
$ ls
dir2  dir3  file5
$ rmdir file5
rmdir: failed to remove ‘file5’: Not a directory
$ rm file5
$ ls
dir2  dir3

By default rmdir can only delete empty directories, therefore we had to use rm to delete a regular file. Try to delete the deleting directory:

$ cd ~/linux_essentials-2.4/
$ ls
copying  creating  deleting  globs  moving
$ rmdir deleting
rmdir: failed to remove ‘deleting’: Directory not empty
$ ls -l deleting
total 0
drwxrwxr-x. 2 emma emma 6 Mar 26 14:58 directories
drwxrwxr-x. 2 emma emma 6 Mar 26 14:58 files

By default, rmdir refuses to delete a directory that is not empty. Use rmdir to remove one of the empty subdirectories of the deleting directory:

$ ls -a deleting/files
.  ..
$ rmdir deleting/files
$ ls -l deleting
directories

Deleting large numbers of files or deep directory structures with many subdirectories may seem tedious, but it is actually easy. By default, rm only works on regular files. The -r option is used to override this behavior. Be careful, rm -r is an excellent foot gun! When you use the -r option, rm will not only delete any directories, but everything within that directory, including subdirectories and their contents. See for yourself how rm -r works:

$ ls
copying  creating  deleting  globs  moving
$ rm deleting
rm: cannot remove ‘deleting’: Is a directory
$ ls -l deleting
total 0
drwxrwxr-x. 2 emma emma 6 Mar 26 14:58 directories
$ rm -r deleting
$ ls
copying  creating  globs  moving

Notice how deleting is gone, even tough it was not empty? Like mvrm has a -i option to prompt you before doing anything. Use rm -ri to remove directories from moving section that are no longer needed:

$ find
.
./creating
./moving
./moving/dir2
./moving/dir2/file2
./moving/dir2/file3
./moving/dir3
./moving/dir3/file1
./globs
./globs/question1
./globs/question2012
./globs/question23
./globs/question13
./globs/question14
./globs/star10
./globs/star1100
./globs/star2002
./globs/star2013
./globs/question15
./copying
./copying/files
./copying/directories
$ rm -ri moving
rm: descend into directory ‘moving’? y
rm: descend into directory ‘moving/dir2’? y
rm: remove regular empty file ‘moving/dir2/file2’? y
rm: remove regular empty file ‘moving/dir2/file3’? y
rm: remove directory ‘moving/dir2’? y
rm: descend into directory ‘moving/dir3’? y
rm: remove regular empty file ‘moving/dir3/file1’? y
rm: remove directory ‘moving/dir3’? y
rm: remove directory ‘moving’? y

Copying Files and Directories

The cp command is used to copy files and directories. Copy a few files into the copying directory:

$ cd ~/linux_essentials-2.4/copying
$ ls
directories  files
$ cp /etc/nsswitch.conf files/nsswitch.conf
$ cp /etc/issue /etc/hostname files

If the last argument is a directory, cp will create a copy of the previous arguments inside the directory. Like mv, multiple files can be specified at once, as long as the target is a directory.

When both operands of cp are files and both files exist, cp overwrites the second file with a copy of the first file. Let’s practice this by overwrite the issue file with the hostname file:

$ cd ~/linux_essentials-2.4/copying/files
$ ls
hostname  issue  nsswitch.conf
$ cat hostname
mycomputer
$ cat issue
Debian GNU/Linux 9 \n \l

$ cp hostname issue
$ cat issue
mycomputer

Now let’s try to create a copy of the files directory within the directories directory:

$ cd ~/linux_essentials-2.4/copying
$ cp files directories
cp: omitting directory ‘files’

As you can see, cp by default only works on individual files. To copy a directory, you use the -r option. Keep in mind that the -r option will cause cp to also copy the contents of the directory you are copying:

$ cp -r files directories
$ find
.
./files
./files/nsswitch.conf
./files/fstab
./files/hostname
./directories
./directories/files
./directories/files/nsswitch.conf
./directories/files/fstab
./directories/files/hostname

Notice how when an existing directory was used as the destination, cp creates a copy of the source directory inside of it? If the destination doesn’t exist, it will create it and fill it with the contents of the source directory:

$ cp -r files files2
$ find
.
./files
./files/nsswitch.conf
./files/fstab
./files/hostname
./directories
./directories/files
./directories/files/nsswitch.conf
./directories/files/fstab
./directories/files/hostname
./files2
./files2/nsswitch.conf
./files2/fstab
./files2/hostname

Globbing

What is commonly referred to as globbing is a simple pattern matching language. Command line shells on Linux systems use this language to refer to groups of files whose names match a specific pattern. POSIX.1-2017 specifies the following pattern matching characters:*

Matches any number of any character, including no characters?

Matches any one character[]

Matches a class of characters

In English, this means you can tell your shell to match a pattern instead of a literal string of text. Usually Linux users specify multiple files with a glob instead of typing out each file name. Run the following commands:

$ cd ~/linux_essentials-2.4/globs
$ ls
question1   question14  question2012  star10    star2002
question13  question15  question23    star1100  star2013
$ ls star1*
star10  star1100
$ ls star*
star10  star1100  star2002  star2013
$ ls star2*
star2002  star2013
$ ls star2*2
star2002
$ ls star2013*
star2013

The shell expands * to any number of anything, so your shell interprets star* to mean anything in the relevant context that starts with star. When you run the command ls star*, your shell doesn’t run the ls program with an argument of star*, it looks for files in the current directory that match the pattern star* (including just star), and turns each file matching the pattern into an argument to ls:

$ ls star*

as far as ls is concerned is the equivalent of

$ ls star10  star1100  star2002  star2013

The * character doesn’t mean anything to ls. To prove this, run the following command:

$ ls star\*
ls: cannot access star*: No such file or directory

When you precede a character with a \, you are instructing your shell not to interpret it. In this case, you want ls to have an argument of star* instead of what the glob star* expands to.

The ? expands to any single character. Try the following commands to see for yourself:

$ ls
question1   question14  question2012  star10    star2002
question13  question15  question23    star1100  star2013
$ ls question?
question1
$ ls question1?
question13  question14  question15
$ ls question?3
question13  question23
$ ls question13?
ls: cannot access question13?: No such file or directory

The [] brackets are used to match ranges or classes of characters. The [] brackets work like they do in POSIX regular expressions except with globs the ^ is used instead of !.

Create some files to experiment with:

$ mkdir brackets
$ cd brackets
$ touch file1 file2 file3 file4 filea fileb filec file5 file6 file7

Ranges within [] brackets are expressed using a -:

$ ls
file1  file2  file3  file4  file5  file6  file7  filea  fileb  filec
$ ls file[1-2]
file1  file2
$ ls file[1-3]
file1  file2  file3

Multiple ranges can be specified:

$ ls file[1-25-7]
file1  file2  file5  file6  file7
$ ls file[1-35-6a-c]
file1  file2  file3  file5  file6  filea  fileb  filec

Square brackets can also be used to match a specific set of characters.

$ ls file[1a5]
file1  file5  filea

You can also use the ^ character as the first character to match everything except certain characters.

$ ls file[^a]
file1  file2  file3  file4  file5  file6  file7  fileb  filec

The last thing we will cover in this lesson is character classes. To match a character class, you use [:classname:]. For example, to use the digit class, which matches numerals, you would do something like this:

$ ls file[[:digit:]]
file1  file2  file3  file4  file5  file6  file7
$ touch file1a file11
$ ls file[[:digit:]a]
file1  file2  file3  file4  file5  file6  file7  filea
$ ls file[[:digit:]]a
file1a

The glob file[[:digit:]a], matches file followed by a digit or a.

The character classes supported depends on your current locale. POSIX requires the following character classes for all locales:[:alnum:]

Letters and numbers.[:alpha:]

Upper or lowercase letters.[:blank:]

Spaces and tabs.[:cntrl:]

Control characters, e.g. backspace, bell, NAK, escape.[:digit:]

Numerals (0123456789).[:graph:]

Graphic characters (all characters except ctrl and the space character)[:lower:]

Lowercase letters (a-z).[:print:]

Printable characters (alnumpunct, and the space character).[:punct:]

Punctuation characters, i.e. !&".[:space:]

Whitespace characters, e.g. tabs, spaces, newlines.[:upper:]

Uppercase letters (A-Z).[:xdigit:]

Hexadecimal numerals (usually 0123456789abcdefABCDEF).

Guided Excercises

  1. Given the following, select the directories that would be created by the command mkdir -p /tmp/outfiles/text/today /tmp/infiles/text/today$ pwd /tmp $ find . ./outfiles ./outfiles/text/tmp/tmp/outfiles/tmp/outfiles/text/tmp/outfiles/text/today/tmp/infiles/tmp/infiles/text/tmp/infiles/text/today
  2. What does -v do for mkdirrm, and cp?
  3. What happens if you accidentally attempt to copy three files on the same command line to a file that already exists instead of a directory?
  4. What happens when you use mv to move a directory into itself?
  5. How would you delete all files in your current directory that start with old?
  6. Which of the following files would log_[a-z]_201?_*_01.txt match?log_3_2017_Jan_01.txtlog_A_2017_Feb_01.txtlog_b_2007_Mar_01.txtlog_f_201A_Wednesday_01.txt
  7. Create a few globs to match the following list of file names:doc100 doc200 doc301 doc401

Explorational Exercises

  1. Use the cp man page to find out how to make a copy of a file and have the permissions and modification time match the original.
  2. What does the rmdir -p command do? Experiment with it and explain how it differs from rm -r.
  3. DO NOT ACTUALLY EXECUTE THIS COMMAND: What do you think rm -ri /* will do? (HONESTLY, DO NOT ATTEMPT TO DO THIS!)
  4. Other than using -i, is it possible to prevent mv from overwriting destination files?
  5. Explain the command cp -u.

Summary

The Linux command line environment provides tools to manage files. Some commonly used ones are cpmvmkdirrm, and rmdir. These tools, combined with globs, allow users to get a lot of work done very quickly.

Many commands have a -i option, which prompts you before doing anything. Prompting can save you a lot of hassle if you mistyped something.

A lot of commands have a -r option. The -r option usually means recursion. In mathematics and computer science, a recursive function is a function using itself in its definition. When it comes to command line tools, it usually means apply the command to a directory and everything in it.

Commands used in this lesson:cat

Read and output the contents of a file.cp

Copy files or directories.echo

Output a string.find

Traverse a file system tree and search for files matching a specific set of criteria.ls

Show properties of files and directories and list a directory’s contents.mkdir

Create new directories.mv

Move or rename files or directories.pwd

Output the current working directory.rm

Delete files or directories.rmdir

Delete directories.touch

Create new empty files or update an existing file’s modification timestamp.

Answers to Guided Exercises

  1. Given the following, select the directories that would be created by the command mkdir -p /tmp/outfiles/text/today /tmp/infiles/text/today$ pwd /tmp $ find . ./outfiles ./outfiles/textThe marked directories would be created. The directories /tmp/tmp/outfiles, and /tmp/outfiles/text already exist, so mkdir will ignore them./tmp/tmp/outfiles/tmp/outfiles/text/tmp/outfiles/text/todayX/tmp/infilesX/tmp/infiles/textX/tmp/infiles/text/todayX
  2. What does -v do for mkdirrm, and cp?Typically -v turns on verbose output. It causes the respective programs to output what they are doing as they are doing it:$ rm -v a b removed ‘a’ removed ‘b’ $ mv -v a b ‘a’ -> ‘b’ $ cp -v b c ‘b’ -> ‘c’
  3. What happens if you accidentally attempt to copy three files on the same command line to a file that already exists instead of a directory?cp will refuse to do anything and output an error message:$ touch a b c d $ cp a b c d cp: target ‘d’ is not a directory
  4. What happens when you use mv to move a directory into itself?You will get an error message telling you mv cannot do that.$ mv a a mv: cannot move ‘a’ to a subdirectory of itself, ‘a/a’
  5. How would you delete all files in your current directory that start with old?You would use the glob old* with rm:$ rm old*
  6. Which of the follwing files would log_[a-z]_201?_*_01.txt match?log_3_2017_Jan_01.txtlog_A_2017_Feb_01.txtXlog_b_2007_Mar_01.txtlog_f_201A_Wednesday_01.txtX$ ls log_[a-z]_201?_*_01.txt log_f_201A_Wednesday_01.txtlog_[a-z] matches log_ followed by any lower case letter, so both log_f_201A_Wednesday_01.txt and log_b_2007_Mar_01.txt match. _201? matches any single character, so only log_f_201A_Wednesday_01.txt matches. Finally *_01.txt matches anything that ends with _01.txt, so our remaining option matches.
  7. Create a few globs to match the following list of file names:doc100 doc200 doc301 doc401There are several solutions. Here are some of them:doc* doc[1-4]* doc?0? doc[1-4]0[12] doc[1-4]0?

Answers to Explorational Exercises

  1. Use the cp man page to find out how to make a copy of a file and have the permissions and modification time match the original.You would use the -p option. From the man page:$ man cp -p same as –preserve=mode,ownership,timestamps –preserve[=ATTR_LIST] preserve the specified attributes (default: mode,ownership,time‐ stamps), if possible additional attributes: context, links, xattr, all
  2. What does the rmdir -p option do? Experiment with it and explain how it differs from rm -r.It causes rmdir to behave similarly to mkdir -p. If passed a tree of empty directories, it will remove all of them.$ find . ./a ./a/b ./a/b/c $ rmdir -p a/b/c $ ls
  3. DO NOT ACTUALLY EXECUTE THIS COMMAND: What do you think rm -ri /* will do? (HONESTLY, DO NOT ATTEMPT TO DO THIS!)It will remove all files and directories writable by your user account. This includes any network file systems.
  4. Other than using -i, is it possible to prevent mv from overwriting destination files?Yes, the -n or --no-clobber option prevents mv from overwriting files.$ cat a a $ cat b b $ mv -n a b $ cat b b
  5. Explain cp -u.The -u option causes cp to only copy a file if the destination is missing or older than the source file.$ ls -l total 24K drwxr-xr-x 123 emma student 12K Feb 2 05:34 .. drwxr-xr-x 2 emma student 4.0K Feb 2 06:56 . -rw-r–r– 1 emma student 2 Feb 2 06:56 a -rw-r–r– 1 emma student 2 Feb 2 07:00 b $ cat a a $ cat b b $ cp -u a b $ cat b b $ cp -u a c $ ls -l total 12 -rw-r–r– 1 emma student 2 Feb 2 06:56 a -rw-r–r– 1 emma student 2 Feb 2 07:00 b -rw-r–r– 1 emma student 2 Feb 2 07:00 c