Episode 6 File management part 2

In this episode, we continue looking at managing files and directories using cp, rm, mkdir, and rmdir. We also show off the tree command and revisit creating an alias in our .bashrc.

1 September 2015

[Rhythmic, dark electronic intro music]


Welcome back to Command Line TV. In this episode we’ll continue our look at

file management using cp, rm and the mkdir/rmdir commands.


So now that we’ve finished up on the mv command, I know that there’s also the cp command.

Is there much difference between those two?


The main difference is just that mv will take its source files and rename

them or put them somewhere else, so then the source files don’t exist anymore.

cp will recreate the files by making a copy of the content,

so your source files will continue to exist when you use cp.

Other than that, a lot of it is the same. So if I look at the help for cp,

cp --help | less

you see the same formats here with either source and destination,

or multiple sources followed by a directory. And then a lot of the options are the same as well.

I can do interactive and no-clobber for the same reasons with cp and

there are a few other things it supports that mv does not.

So let’s try out the simplest form of it. I’ve got a web log here that’s marked as being July 11th.

If I just want to make a copy of that file in place,

I can specify cp and then the filename and then give it a different filename.

cp weblog-2015-07-11.txt weblog-2015-07-12.txt

So maybe I just put the next day’s date there. And now when I did mv this

would be like a rename but now it’s a copy so the original still exists.

And if we look at the detailed listing they have exactly the same size and

ls -l

they have the same contents. So if I look at the first couple of lines in both of those files,

head -3 weblog*

they’re exactly the same. So it’s just making a copy of the data under a different filename.

Now another form of cp is to copy multiple files into a new directory or

into an existing directory even. So if I go down into my thinkjava/figs

cd thinkjava/figs

where I moved all of my .fig and .eps files into these separate subdirectories, I could do that.

So right now inside of the fig directory I’ve got a bunch of files called

ls fig

“something” .fig and I can do cp from fig/*, so that means all of the

files within that fig directory. I want to move them to the current directory.

cp fig/* .

The way we specify current directory is just with a single dot,

which makes it really easy to miss when you see this command like,

printed on a web page or something. A lot of times that dot will disappear

or you’ll think it’s a speck of dust on your screen or something.

But that dot is important because it specifies the destination directory.

So if I do that – now all of those .fig files are in the current directory,

but they also have copies in fig as well. So it keeps both.

So that’s both formats of the cp command.

One other option that cp and mv both support that we haven’t touched on yet is called verbose.

So a lot of commands have a -v option which means verbose.

It means it should explain what’s going on as it happens.

And this is as opposed to usual – like most Unix commands will be very

quiet and they will only put out a message when there is something seriously wrong.

So we can do – let’s do the same thing with the eps folder –

so cp eps/* into the current directory. But this time I’m going to use the -v option.

cp -v eps/* .

And it will give me a transcript of all of the copies that it had to do in order to implement that.

So if you want to copy an entire directory worth of files, the cp command can do that too.

Let’s say I’m here where I’ve got this django project and I want to make a

copy of that to start new projects out of it. So if I do cp django and

then we’re going to call it proj1 – at first it will refuse to do that –

cp django proj1

it says “omitting the directory”. So there’s an option that will tell cp

it’s okay to make copies of entire directories and that’s -r for recursive.

cp -r django proj1

So cp -r django proj1 means now that I’ve got a proj1 directory that

has the same contents as the original django directory.

ls django
ls proj1

And it’s fun to combine that with the verbose because then you get to see

lots and lots of files being created. So let’s just try it again to create proj2.

cp -rv django proj2

And you can see that even down to the sub-directories –

like it’s making a copy of this django/media/sass.scss and putting the

same structure within the proj2 directory. And so we can see django compared to proj2.

ls -l django
ls -l proj2

I guess a good thing to point out is that its also copying the date as well –

the date and time as well.


Yeah, this date and time, it’s – like, the originals were June 1st and

then the copy actually gets a new timestamp. So it’s not preserving the timestamps currently.

There is a way for it to do that, which is the -a option.

If we go back to the help screen, -a stands for archive and that means

it preserves all sorts of information. One of them is timestamps but it can

also be permissions and some other stuff. So if I repeat that last cp command,

instead of -rv I can type -av and the a for archive includes doing recursive –

cp -av django proj3

so you can keep the -r if you want to but it is not needed anymore because -a implies -r.

So I make a copy of django into proj3 and now if I compare django to

proj3 we see that the timestamps get preserved as well.

ls -l django
ls -l proj3

So professor, earlier in this episode we actually made a directory to do some work in it.

Can we go more in depth as to what the capabilities are of that?


Yeah, so mkdir offers – basically it’s one of the very simple commands –

you just type mkdir and then the directory name or multiple directory names.

But there is one cool thing that it supports that’s very useful – which is,

imagine that you want to create a tree structure of a directory like, down a couple of levels.

So instead of just creating a single directory I might want to – let’s say,

create proj4/assets/js because that’s where I want to put my javascript

mkdir proj4/assets/js

files for my web project or something. The trouble with this is that

mkdir will refuse to create that if the proj4 itself doesn’t exist, right.

So this would mean I want proj4 as a directory, within that I want assets as a directory,

within that I want js as a directory. That’s three separate directories

that it’s supposed to create and it will not do that. So one solution is to do it one at a time.

I could say mkdir proj4 press enter, and then once that exists I can do

mkdir proj4
mkdir proj4/assets

mkdir proj4/assets press enter, and so on. But the cooler way is mkdir supports an option -p.

This just means to create all of the parent directories necessary to

create what I said and so just mkdir -p and now within proj4

mkdir -p proj4/assets/js

let’s see the top level first – within proj4 I’ve got assets,

within that I’ve got js, and that is then empty but it created the entire tree.

ls proj4
ls proj4/assets

And if we did the tree command it would show the entire structure as well correct?


Yeah, I don’t know if we used tree before, it’s a great command though.

tree proj4

So tree is kind of a way to visualize a directory tree using these kind

of line drawing characters. It doesn’t exist on every Unix system and you might

have to install it but it’s something definitely worth having. So it looks like that.

tree django

Yeah, so we can see that that tree structure that we created using mkdir -p.

Now for removing directories there’s a command rmdir.

So if I decide I don’t want that js folder, I could say rmdir

proj4/assets/js and it would remove that one folder from assets.

rmdir proj4/assets/js

The parent directories still exist, it only removed the bottom-most one that I specified.

tree proj4

What if I want to remove the whole proj4 directory?

So if I tried rmdir proj4 it will actually complain because –

rmdir proj4

this is unusual, most Unix commands will just do something awful without complaining!

But this one actually will prevent you from removing a directory unless it’s completely empty –

it cannot have any subdirectories or any files in it, even the hidden dot files.

So, that doesn’t work and I would have to do them one at a time, like,

rmdir proj4/assets and then rmdir proj4. And rmdir doesn’t have an

rmdir proj4/assets
rmdir proj4

option that lets you shortcut that. However, there’s another command which is just rm.

So rm has a deserved reputation of being a very sharp tool.

It will delete lots and lots of stuff very quickly and if you mistype a

command a little bit you can really make things difficult on yourself.

So by default rm will just delete files, so let’s take a look here. I’ve got these weblog files.

Let’s say I want to rm weblog*, right – and press enter.

rm weblog*

Very quick and quiet, but those two files are gone. So that’s rm.

Now if you want to remove a directory, rm – for example proj2

rm proj2

that doesn’t work because it’s a directory and rm by default only removes files.

But it doesn’t take much to convince rm to do more destructive things.

So the one option we’ll learn is -r which is of course is for recursive.

rm -r proj2

And this means it will go into that directory, delete all of the files,

any subdirectories, and their files, and so on. The entire tree, it will just blow away.

And again it’s very fast and now all of those files are gone.

So is there a way we can protect ourselves from rm -r?


Set up another alias on it.


Yeah, exactly. So rm – let’s take a look at the help first.

rm --help|less

It supports the ‘interactive’ just like mv and cp did –

which means before every removal it will prompt. Maybe you don’t want that

but I think it’s not a bad idea to have an alias for that. So let’s try that.

Where did I keep my aliases before?


It was .bash s h? Oh, rc.


.bashrc, yep. So I’m going to go in there and let’s add an alias for rm='rm -i'.

nano ~/.bashrc
alias rm='rm -i'

And I’ll put a little comment above this [laughs] okay.

So now I’ve got an alias for rm that doesn’t take effect immediately,

I would have to close the terminal and reopen another one, or source that file.

source ~/.bashrc

Now it’s there as an alias. And so now if I do rm -r proj1 it will slow me down quite a lot.

rm -r proj1

First of all, “Do you want to descend into this directory” in the first place? Yes.

“Do you want to descend into templates?” Yes. “Do you want to remove this

file which is empty?” Okay. So this obviously slows you down if you type something by accident.

But if you really seriously want to remove a bunch of stuff,

one way to get around an alias is – by the way to stop that I just hit

control-C to cancel that command. Control-C wouldn’t undo any deletes that have already happened,

it just cancels it where it is in the process. So if I want to actually delete that whole directory,

one way to bypass an alias is to put a backslash before the command.

\rm -r proj1

And now if I’ve got an rm as an alias, this will skip the alias and just

go to the regular command. So that will now delete all of the proj1 directory very fast.

So it’s a little bit of a trade off, right? If rm with interactive is asking too many questions,

then what you’re going to do when you really need to delete something is just type \rm.

And actually I’ve acquired that habit personally, my own .bashrc has rm

aliased to rm -i but I always – I never type just rm.

It’s just in my bones now, or in my fingers to type \rm whenever I want to delete something,

so the alias doesn’t really do me any good.

One of the other options of rm that can be especially dangerous is the -f.

So we see here -f means force. Force basically means if there is

something preventing deletion that can be resolved – so for example,

if I’ve set up a permission on a file so that I’m not allowed to write to it,

to delete it – it can try to actually modify the permissions in order to allow that again.

And so if I’m allowed to change the permission to allow me to delete it

then it will still delete it. So that’s a pretty serious thing.

When you combine recursive with forcing that really becomes quite dangerous

and so rm -rf even in like, nerd culture is known to be like a very dangerous thing to do,

and it actually gives me chills a little bit even to type it.

And one thing you never ever want to do probably is –

I can’t even type this – I’ve got to separate the rm so it doesn’t cause me real problems –

r m -rf /

is if you put a slash here, slash is a way to refer to the top level of your file system,

the root directory. And so this means start at the top of my entire disk or

even multiple disks and try to delete everything it can.

So that’s a pretty awful command and you should probably try never to type it.


Alright so today we covered a lot of file management using the copy,

the remove, the move, as well as the make and remove directories.


So next time I think we’re going to look at Image Magick which is a pretty

exciting suite of command line tools for doing image processing.

You can do things like convert images from one format to another.

You can automate things like applying filters to images,

shrinking and cropping them – all sorts of things. So I think that’s going

to be a pretty exciting one because we’re going to move beyond just the

simple commands that do things you already know how to do on a maybe desktop file manager.

And we’re going to start to see some things that we can do on the command

line that are pretty different. So see you then!

[Dark electronic beat]

[Captions by Christian Lopes and Christopher League]