-
Okay, can everyone hear me okay?
-
Okay, so welcome back.
-
I'm gonna address a couple of items
in kind of the administratrivia.
-
With the end of the first week,
-
we sent an email, noticing you that
-
we have uploaded the videos for the first
week, so you can now find them online.
-
They have all the screen recordings for the things
that we were doing, so you can go back to them.
-
Look if you're were confused about if
we did something quick and, again,
-
feel free to ask us any questions if anything in the
lecture notes is not clear. We also sent you a
-
survey so you can give us feedback
about what was not clear,
-
what items you would want a
more thorough explanation or
-
just any other item, if you're finding
the exercises too hard, too easy,
-
go into that URL and we'll really
-
appreciate getting that feedback, because
that will make the course better
-
for the remaining lectures and for
future iterations of the course.
-
With that out of the way
-
Oh, and we're gonna try to upload the
videos in a more timely manner.
-
We don't want to kind of wait until the end of
the week for that. So keep tuned for that.
-
That out of the way,
-
now I'm gonna
-
This lecture's called command-line
environment and we're
-
going to cover a few different topics. So the
-
main topics we're gonna
-
cover, so you can keep track,
-
it's probably better here,
-
keep track of what I'm talking.
-
The first is gonna be job control.
-
The second one is going to be
-
terminal multiplexers.
-
Then I'm going to explain what dotfiles
are and how to configure your shell.
-
And lastly, how to efficiently work with
remote machines. So if things are not
-
fully clear, kind of keep the structure.
-
They all kind of interact in some
way, of how you use your terminal,
-
but they are somewhat separate
topics, so keep that in mind.
-
So let's go with job control. So far we have
been using the shell in a very, kind of
-
mono-command way. Like, you
execute a command and then
-
the command executes, then you get some output,
and that's all about what you can do.
-
And if you want to run several
things, it's not clear
-
how you will do it. Or if you want to stop
the execution of a program, it's again,
-
like how do I know how to stop a program?
-
Let's showcase this with a command called sleep.
-
Sleep is a command that takes an argument,
-
and that argument is going to be an
integer number, and it will sleep.
-
It will just kind of be there, on the
background, for that many seconds.
-
So if we do something like sleep 20, this process
is gonna be sleeping for 20 seconds.
-
But we don't want to wait 20 seconds
for the command to complete.
-
So what we can do is type "Ctrl+C".
-
By typing "Ctrl+C"
-
We can see that, here, the terminal let us know,
-
and it's part of the syntax that we covered
in the editors / Vim lecture,
-
that we typed "Ctrl+C" and it stopped
the execution of the process.
-
What is actually going on here
-
is that this is using a UNIX communication
mechanism called signals.
-
When we type "Ctrl+C",
-
what the terminal did for us,
or the shell did for us,
-
is send a signal called SIGINT,
-
that stands for SIGnal INTerrupt, that
tells the program to stop itself.
-
And there are many, many, many signals
of this kind. If you do man signal,
-
and just go down a little bit,
here you have a list of them.
-
They all have number identifiers,
-
they have kind of a short name
and you can find a description.
-
So for example, the one I have just
described is here, number 2, SIGINT.
-
This is the signal that a terminal will send to a
program when it wants to interrupt its execution.
-
A few more to be familiar with
-
is SIGQUIT, this is
-
again, if you work from a terminal and you
want to quit the execution of a program.
-
For most programs it will do the same thing,
-
but we're gonna showcase now a program
which will be different,
-
and this is the signal that will be sent.
-
It can be confusing sometimes. Looking at
these signals, for example, the SIGTERM is
-
for most cases equivalent to SIGINT and SIGQUIT
-
but it's just when it's not
sent through a terminal.
-
A few more that we're gonna
-
cover is SIGHUP, it's when there's
like a hang-up in the terminal.
-
So for example, when you are in your
terminal, if you close your terminal
-
and there are still things
running in the terminal,
-
that's the signal that the program is gonna send
-
to all the processes to tell
that they should close,
-
like there was a hang-up in the
command line communication
-
and they should close now.
-
Signals can do more things than just stopping, interrupting
programs and asking them to finish.
-
You can for example use the
-
SIGSTOP to pause the execution of the
program, and then you can use the
-
SIGCONT command for continuing, to continue the execution
of the program at a point later in time.
-
Since all of this might be slightly too
abstract, let's see a few examples.
-
First, let's showcase a
-
Python program. I'm going to very
quickly go through the program.
-
This is a Python program,
-
that like most python programs,
-
is importing this signal library and
-
is defining this handler here.
And this handler is writing,
-
"Oh, I got a SIGINT, but
I'm not gonna stop here".
-
And after that,
-
we tell Python that we want this program,
when it gets a SIGINT, to stop.
-
The rest of the program is a very silly program
that is just going to be printing numbers.
-
So let's see this in action.
-
We do Python SIGINT.
-
And it's counting. We try doing
"Ctrl+C", this sends a SIGINT,
-
but the program didn't actually stop. This
is because we have a way in the program of
-
dealing with this exception,
and we didn't want to exit.
-
If we send a SIGQUIT, which is done through
-
"Ctrl+\", here, we can see that since the program
doesn't have a way of dealing with SIGQUIT,
-
it does the default operation, which is
-
terminate the program.
-
And you could use this, for example,
-
if someone Ctrl+C's your program, and your
program is supposed to do something,
-
like you maybe want to save the intermediate
state of your program
-
to a file, so you can recover it for later.
-
This is how you could write a handler like this.
-
Can you repeat the question?
-
What did you type right now, when it stopped?
-
So I...
-
So what I typed is, I type
"Ctrl+C" to try to stop it
-
but it didn't, because SIGINT is captured
by the program. Then I type
-
"Ctrl+\", which sends a SIGQUIT,
which is a different signal,
-
and this signal is not captured by the program.
-
It's also worth mentioning
that there is a couple of
-
signals that cannot be captured by software.
There is a couple of signals
-
like SIGKILL
-
that cannot be captured. Like that, it will
-
terminate the execution of the
process, no matter what.
-
And it can be sometimes harmful.
You do not want to be using it by
-
default, because this can leave for example an
orphan child, orphaned children processes.
-
Like if a process has other small children
processes that it started, and you
-
SIGKILL it, all of those will
keep running in there,
-
but they won't have a parent, and you can maybe
have a really weird behavior going on.
-
What signal is given to the
program if we log off?
-
If you log off?
-
That would be... so for example, if you're in an
SSH connection and you close the connection,
-
that is the hang-up signal,
-
SIGHUP, which I'm gonna cover in an example.
So this is what would be sent up.
-
And you could write for example, if you want
the process to keep working even if you close
-
that, you can write a wrapper around
that to ignore that signal.
-
Let's display what we could do
with the stop and continue.
-
So, for example, we can start a really long process.
Let's sleep a thousand, we're gonna take forever.
-
We can control-c,
-
"Ctrl+Z", sorry,
-
and if we do "Ctrl+Z" we can see that the
terminal is saying "it's suspended".
-
What this actually meant is that this process
was sent a SIGSTOP signal and now is
-
still there, you could continue its execution, but right
now it's completely stopped and in the background
-
and we can launch a different program.
-
When we try to run this program,
-
please notice that I have included
an "&" at the end.
-
This tells bash that I want this program
to start running in the background.
-
This is kind of related to all these
-
concepts of running programs in
the shell, but backgrounded.
-
And what is gonna happen is
the program is gonna start
-
but it's not gonna take over my prompt.
-
If I just ran this command without
this, I could not do anything.
-
I would have no access to the prompt
until the command either finished
-
or I ended it abruptly. But if I do this,
-
it's saying "there's a new
process which is this".
-
This is the process identifying number,
-
we can ignore this for now.
-
If I type the command "jobs", I get the
output that I have a suspended job
-
that is the "sleep 1000" job.
-
And then I have another running job,
-
which is this "NOHUP sleep 2000".
-
Say I want to continue the first job.
-
The first job is suspended,
it's not executing anymore.
-
I can continue that doing "BG %1"
-
That "%" is referring to the fact that
I want to refer to this specific
-
process. And now, if I do that
and I look at the jobs,
-
now this job is running again. Now
-
both of them are running.
-
If I wanted to stop these all,
I can use the kill command.
-
The kill command
-
is for killing jobs,
-
which is just stopping them, intuitively,
-
but actually it's really useful.
-
The kill command just allows you
to send any sort of Unix signal.
-
So here for example, instead
of killing it completely,
-
we just send a stop signal.
-
Here I'm gonna send a stop signal, which
is gonna pause the process again.
-
I still have to include the identifier,
-
because without the identifier the shell wouldn't know
whether to stop the first one or the second one.
-
Now it's said this has been suspended,
because there was a signal sent.
-
If I do "jobs", again, we can see
that the second one is running
-
and the first one has been stopped.
-
Going back to one of the questions,
-
what happens when you close
the cell, for example,
-
and why sometimes people will say that
you should use this NOHUP command
-
before your run jobs in a remote session.
-
This is because if we try to send
a hung up command to the first job
-
it's gonna, in a similar fashion
as the other signals,
-
it's gonna hang it up and that's
gonna terminate the job.
-
And the first job isn't there anymore
-
whereas we have still the second job running.
-
However, if we try to send the
signal to the second job
-
what will happen if we close
our terminal right now
-
is it's still running.
-
Like NOHUP, what it's doing
is kind of encapsulating
-
whatever command you're executing and
-
ignoring wherever you get a hang up signal,
-
and just ignoring that so it can keep running.
-
And if we send the "kill"
signal to the second job,
-
that one can't be ignored and that
will kill the job, no matter what.
-
And we don't have any jobs anymore.
-
That kind of completes the
section on job control.
-
Any questions so far? Anything
that wasn't fully clear?
-
What does BG do?
-
So BG...
-
There are like two commands. Whenever you
have a command that has been backgrounded
-
and is stopped you can use
BG (short for background)
-
to continue that process running
on the background.
-
That's equivalent of just kind of sending it
-
a continue signal, so it keeps running.
-
And then there's another one which
is called FG, if you want to
-
recover it to the foreground and you want
to reattach your standard output.
-
Okay, good.
-
Jobs are useful and in general, I
think knowing about signals can be
-
really beneficial when dealing
with some part of Unix
-
but most of the time what you actually want
to do is something along the lines of
-
having your editor in one side and then
the program in another, and maybe
-
monitoring what the resource
consumption is in our tab.
-
We could achieve this using probably
what you have seen a lot of the time,
-
which is just opening more windows.
-
We can keep opening terminal windows.
-
But the fact is there are kind of more
convenient solutions to this and
-
this is what a terminal multiplexer does.
-
A terminal multiplexer like tmux
-
will let you create different workspaces
that you can work in,
-
and quickly kind of,
-
this has a huge variety of functionality,
-
It will let you rearrange the environment and
it will let you have different sessions.
-
There's another more...
-
older command, which is called "screen",
-
that might be more readily available.
-
But I think the concept kind
of extrapolates to both.
-
We recommend tmux, that you go and learn it.
-
And in fact, we have exercises on it.
-
I'm gonna showcase a different
scenario right now.
-
So whenever I talked...
-
Oh, let me make a quick note.
-
There are kind of three core concepts
in tmux, that I'm gonna go through and
-
the main idea is that there are what is called
-
"sessions".
-
Sessions have "windows" and
-
windows have "panes".
-
It's gonna be kind of useful to
keep this hierarchy in mind.
-
You can pretty much equate "windows" to what
"tabs" are in other editors and others,
-
like for example your web browser.
-
I'm gonna go through the features, mainly
what you can do at the different levels.
-
So first, when we do tmux, that starts a session.
-
And here right now it seems like nothing changed
-
but what's happening right now is we're within a shell
that is different from the one we started before.
-
So in our shell we started
a process, that is tmux
-
and that tmux started a different process,
which is the shell we're currently in.
-
And the nice thing about this is that
-
that tmux process is separate from
the original shell process.
-
So
-
here, we can do things.
-
We can do "ls -la", for example, to
tell us what is going on in here.
-
And then we can start running our program,
and it will start running in there
-
and we can do "Ctrl+A d", for example, to detach
-
to detach from the session.
-
And if we do "tmux a"
-
that's gonna reattach us to the session.
-
So the process,
-
we abandon the process counting numbers.
-
This really silly Python program
that was just counting numbers,
-
we left it running there.
-
And if we tmux...
-
Hey, the process is still running there.
-
And we could close this entire
terminal and open a new one and
-
we could still reattach because this
tmux session is still running.
-
Again, we can...
-
Before I go any further.
-
Pretty much... Unlike Vim, where
you have this notion of modes,
-
tmux will work in a more emacsy way, which is
-
every command, pretty much every command in tmux,
-
you could enter it through the...
-
it has a command line, that we could use.
-
But I recommend you to get familiar
with the key bindings.
-
It can be somehow non intuitive at first,
-
but once you get used to them...
-
"Ctrl+C", yeah
-
When you get familiar with them, you will be much faster
just using the key bindings than using the commands.
-
One note about the key bindings: all the
key bindings have a form that is like
-
you type a prefix and then some key.
-
So for example, to detach we
do "Ctrl+A" and then "D".
-
This means you press "Ctrl+A" first, you release
that, and then press "D" to detach.
-
On default tmux, the prefix is "Ctrl+B",
-
but you will find that most people
will have this remapped to "Ctrl+A"
-
because it's a much more ergonomic
type on the keyboard.
-
You can find more about how to do these
things in one of the exercises,
-
where we link you to the basics and how to do some
kind of quality of life modifications to tmux.
-
Going back to the concept of sessions,
-
we can create a new session just
doing something like tmux new
-
and we can give sessions names.
-
So we can do like "tmux new -t foobar"
-
and this is a completely different
session, that we have started.
-
We can work here, we can detach from it.
-
"tmux ls" will tell us that we
have two different sessions:
-
the first one is named "0", because
I didn't give it a name,
-
and the second one is called "foobar".
-
I can attach the foobar session
-
and I can end it.
-
And it's really nice because
-
having this you can kind of work
in completely different projects.
-
For example, having two different
tmux sessions and different
-
editor sessions, different processes running...
-
When you are within a session, we
start with the concept of windows.
-
Here we have a single window, but we
can use "Ctrl+A c" (for "create")
-
to open a new window.
-
And here nothing is executing.
-
What it's doing is, tmux has
opened a new shell for us
-
and we can start running another
one of these programs here.
-
And to quickly jump between the tabs,
we can do "Ctrl+A" and "previous",
-
"p" for "previous",
-
and that will go up to the previous window.
-
"Ctrl+A" "next", to go to the next window.
-
You can also use the numbers. So if we
start opening a lot of these tabs,
-
we could use "Ctrl+A 1", to
specifically jump to the
-
to the window that is number "1".
-
And, lastly, it's also pretty
useful to know sometimes
-
that you can rename them.
-
For example here I'm executing
this Python process,
-
but that might not be really
informative and I want...
-
I maybe want to have something like
execution or something like that and
-
that will rename the name of that window so
you can have this really neatly organized.
-
This still doesn't solve the need when you want to
have two things at the same time in your terminal,
-
like in the same display.
-
This is what panes are for. Right now, here
-
we have a window with a single pane
-
(all the windows that we have opened
so far have a single pane).
-
But if we do 'Ctrl+A "'
-
this will split the current display
into two different panes.
-
So, you see, the one we open below is a different
shell from the one we have above,
-
and we can run any process that we want here.
-
We can keep splitting this, if we do "Ctrl+A %"
-
that will split vertically. And you can kind of
-
rearrange these tabs using a
lot of different commands.
-
One that I find very useful, when you are
starting and it's kind of frustrating,
-
rearranging them.
-
Before I explain that, to move
through these panes, which is
-
something you want to be doing all the time
-
You just do "Ctrl+A" and the arrow
keys, and that will let you quickly
-
navigate through the different
windows, and execute again...
-
I'm doing a lot of "ls -a"
-
I can do "HTOP", that we'll explain in
the debugging and profiling lecture.
-
And we can just navigate through them, again
-
like to rearrange there's
another slew of commands,
-
you will go through some in the Exercises
-
"Ctrl+A" space is pretty neat, because it
will kind of equispace the current ones
-
and let you through different layouts.
-
Some of them are too small for my current
-
terminal config, but that covers,
I think, most of it.
-
Oh, there's also,
-
here, for example, this Vim execution
that we have started,
-
is too small for what the current tmux pane is.
-
So one of the things that really is
much more convenient to do in tmux,
-
in contrast to having multiple
terminal windows, is that
-
you can zoom into this, you can ask
by doing "Ctrl+A z", for "zoom".
-
It will expand the pane to
take over all the space,
-
and then "Ctrl+A z", again will go back to it.
-
Any questions for terminal multiplexers,
or like, tmux concretely?
-
Is it running all the same thing?
-
Like, is there any difference in execution
between running it in different windows?
-
Is it really just doing it all the
same, so that you can see it?
-
Yeah, it wouldn't be any different from having
two terminal windows open in your computer.
-
Like both of them are gonna be running.
Of course, when it gets to the CPU,
-
this is gonna be multiplexed again.
-
Like there's like a timesharing
mechanism going there
-
but there's no difference.
-
tmux is just making this much more convenient
to use by giving you this visual layout
-
that you can quickly manipulate through.
-
And one of the main advantages will come
when we reach the remote machines
-
because you can leave one of these, we can
detach from one of these tmux systems,
-
close the connection and even
if we close the connection and
-
and the terminal is gonna send a hang-up signal,
-
that's not gonna close all the
tmux's that have been started.
-
Any other questions?
-
Let me disable the key-caster.
-
So now we're gonna move into the topic
of dotfiles and, in general,
-
how to kind of configure your shell
to do the things you want to do
-
and mainly how to do them quicker
and in a more convenient way.
-
I'm gonna motivate this using aliases first.
-
So what an alias is,
-
is that by now, you might be
starting to do something like
-
a lot of the time, I just want to LS a directory and
I want to display all the contents into a list format
-
and in a human readable thing.
-
And it's fine. Like it's not
that long of a command.
-
But as you start building longer
and longer commands,
-
it can become kind of bothersome having
to retype them again and again.
-
This is one of the reasons
why aliases are useful.
-
Alias is a command that will
be a built-in in your shell,
-
and what it will do is
-
it will remap a short sequence of
characters to a longer sequence.
-
So if I do, for example, here
-
alias ll="ls -lah"
-
If I execute this command, this is gonna call
the "alias" command with this argument
-
and the LS is going to update
-
the environment in my shell
to be aware of this mapping.
-
So if I now do LL,
-
it's executing that command without me
having to type the entire command.
-
It can be really handy for many, many reasons.
-
One thing to note before I go any further is that
-
here, alias is not anything special
compared to other commands,
-
it's just taking a single argument.
-
And there is no space around
this equals and that's
-
because alias takes a single argument
-
and if you try doing
-
something like this, that's giving
it more than one argument
-
and that's not gonna work because
that's not the format it expects.
-
So other use cases that work for aliases,
-
as I was saying,
-
for some things it may be much more convenient,
-
like
-
one of my favorites is git status.
-
It's extremely long, and I don't like typing
that long of a command every so often,
-
because you end up taking a lot of time.
-
So GS will replace for doing the git status
-
You can also use them to alias
things that you mistype often,
-
so you can do "sl=ls",
-
that will work.
-
Other useful mappings are,
-
you might want to alias a command to itself
-
but with a default flag.
-
So here what is going on is I'm creating an alias
-
which is an alias for the move command,
-
which is MV and I'm aliasing it to the
same command but adding the "-i" flag.
-
And this "-i" flag, if you go through the man page
and look at it, it stands for "interactive".
-
And what it will do is it will prompt
me before I do an overwrite.
-
So once I have executed this,
I can do something like
-
I want to move "aliases" into "case".
-
By default "move" won't ask, and if "case"
already exists, it will be over.
-
That's fine, I'm going to overwrite
whatever that's there.
-
But here it's now expanded,
-
"move" has been expanded into this "move -i"
-
and it's using that to ask me
-
"Oh, are you sure you want to overwrite this?"
-
And I can say no, I don't want to lose that file.
-
Lastly, you can use "alias move"
-
to ask for what this alias stands for.
-
So it will tell you so you can quickly make sure
-
what the command that you
are executing actually is.
-
One inconvenient part about, for example,
having aliases is how will you go about
-
persisting them into your current environment?
-
Like, if I were to close this terminal now,
-
all these aliases will go away.
-
And you don't want to be kind
of retyping these commands
-
and more generally, if you start configuring
your shell more and more,
-
you want some way of bootstrapping
all this configuration.
-
You will find that most shell command programs
-
will use some sort of text
based configuration file.
-
And this is what we usually call "dotfiles", because
they start with a dot for historical reasons.
-
So for bash in our case, which is a shell,
-
we can look at the bashrc.
-
For demonstration purposes,
here I have been using ZSH,
-
which is a different shell, and I'm going
to be configuring bash, and starting bash.
-
So if I create an entry here and I say
-
SL maps to LS
-
And I have modified that, and now I start bash.
-
Bash is kind of completely unconfigured,
but now if I do SL...
-
Hm, that's unexpected.
-
Oh, good. Good getting that.
-
So it matters where you config file is,
-
your config file needs to be in your home folder.
-
So your configuration file for
bash will live in that "~",
-
which will expand to your home directory,
-
and then bashrc.
-
And here we can create the alias
-
and now we start a bash session and we do SL.
-
Now it has been loaded, and this is
loaded at the beginning when this
-
bash program is started.
-
All this configuration is loaded and you can, not only use
aliases, they can have a lot of parts of configuration.
-
So for example here, I have a prompt
which is fairly useless.
-
It has just given me the name
of the shell, which is bash,
-
and the version, which is 5.0. I don't
want this to be displayed and
-
as with many things in your shell, this
is just an environment variable.
-
So the "PS1" is just the prompt string
-
for your prompt and
-
we can actually modify this
to just be a "> " symbol.
-
and now that has been modified, and we have
that. But if we exit and call bash again,
-
that was lost. However, if we add this
entry and say, oh we want "PS1"
-
to be
-
this and
-
we call bash again, this has been persisted.
And we can keep modifying this configuration.
-
So maybe we want to include
-
where the
-
working directory that we are is in, and
-
that's telling us the same information
that we had in the other shell.
-
And there are many, many options,
-
shells are highly, highly configurable, and
-
it's not only cells that are configured
through these files,
-
there are many other programs. As we saw for
example in the editors lecture, Vim is also
-
configured this way. We gave you this vimrc
file and told you to put it under your
-
home/.vimrc
-
and this is the same concept, but just
for Vim. It's just giving it a set of
-
instructions that it should load when it's started,
so you can keep a configuration that you want.
-
And even non...
-
kind of a lot of programs will support this. For instance,
my terminal emulator, which is another concept,
-
which is the program that is
-
running the shell, in a way, and displaying
this into the screen in my computer.
-
It can also be configured this way, so
-
if I modify this I can
-
change the size of the font. Like right now, for
example, I have increased the font size a lot
-
for demonstration purposes, but
-
if I change this entry and make it for example
-
28 and write this value, you see that
the size of the font has changed,
-
because I edited this text file that specifies
how my terminal emulator should work.
-
Any questions so far?
-
With dotfiles.
-
Okay, it can be a bit daunting knowing that there
is like this endless wall of configurations,
-
and how do you go about learning
about what can be configured?
-
The good news is that
-
we have linked you to really good
resources in the lecture notes.
-
But the main idea is that a lot of people really like
just configuring these tools and have uploaded
-
their configuration files to GitHub, another
different kind of repositories online.
-
So for example, here we are on GitHub,
-
we search for dotfiles, and
can see that there are like
-
thousands of repositories of people sharing
their configuration files. We have also...
-
Like, the class instructors
have linked our dotfiles.
-
So if you really want to know how
any part of our setup is working
-
you can go through it and try to figure it out.
-
You can also feel free to ask us.
-
If we go for example to this repository here
-
we can see that there's many, many
files that you can configure.
-
For example, there is one for bash, the first couple of ones
are for git, that will be probably be covered in the
-
version control lecture tomorrow.
-
If we go for example to the bash profile, which is
a different form of what we saw in the bashrc,
-
it can be really useful because
you can learn through
-
just looking at the manual page, but the
manual pages is, a lot of the time
-
just kind of like a descriptive explanation
of all the different options
-
and sometimes it's more helpful
-
going through examples of what people have done
and trying to understand why they did it
-
and how it's helping their workflow.
-
We can say here that this person has
done case-insensitive globbing.
-
We covered globbing as this
kind of filename expansion
-
trick in the shell scripting and tools.
-
And here you say no, I don't want this to matter,
-
whether using uppercase and lowercase,
-
and just setting this option in the shell
for these things to work this way
-
Similarly, there is for example aliases.
-
Here you can see a lot of aliases that this
person is doing. For example, "d" for
-
"d" for "Dropbox", sorry, because
that's just much shorter.
-
"g" for "git"...
-
Say we go, for example, with vimrc. It
can be actually very, very informative,
-
going through this and trying
to extract useful information.
-
We do not recommend just kind of getting one huge blob
of this and copying this into your config files,
-
because maybe things are prettier, but you might
not really understand what is going on.
-
Lastly one thing I want to mention
about dotfiles is that
-
people not only try to push these
-
files into GitHub just so other
people can read it, that's
-
one reason. They also make really sure they can
-
reproduce their setup. And to do that
they use a slew of different tools.
-
Oops, went a little too far.
-
So GNU Stow is, for example, one of them
-
and the trick that they are doing is
-
they are kind of putting all their
dotfiles in a folder and they are
-
faking to the system, using
a tool called symlinks,
-
that they are actually what
they're not. I'm gonna
-
draw really quick what I mean by that.
-
So a common folder structure might look
like you have your home folder and
-
in this home folder you might have your
-
bashrc, that contains your bash configuration,
you might have your vimrc and
-
it would be really great if you could
keep this under version control.
-
But the thing is, you might not
want to have a git repository,
-
which will be covered tomorrow,
-
in your home folder.
-
So what people usually do is they
create a dotfiles repository,
-
and then they have entries here for their
-
bashrc and their vimrc. And
this is where actually
-
the files are
-
and what they are doing is they're just
-
telling the OS to forward, whenever anyone
-
wants to read this file or write to this file,
just forward this to this other file.
-
This is a concept called symlinks
-
and it's useful in this scenario,
-
but it in general it's a really
useful tool in UNIX
-
that we haven't covered so far in the lectures
-
but you might be...
-
that you should be familiar with.
-
And in general, the syntax will be "ln -s"
-
for specifying a symbolic link and then
you will put the path to the file
-
that you want to create and then the
-
symlink that you want to create.
-
And
-
All these all these kind of fancy tools
that we're seeing here listed,
-
they all amount to doing some sort of this trick, so
that you can have all your dotfiles neat and tidy
-
into a folder, and then they can be
version-controlled, and they can be
-
symlinked so the rest of the programs can
find them in their default locations.
-
Any questions regarding dotfiles?
-
Do you need to have the dotfiles in your home folder,
and then also dotfiles in the version control folder?
-
So what you will have is,
pretty much every program,
-
for example bash,
-
will always look for "home/.bashrc".
-
That's where the program is going to look for.
-
What you do when you do a symlink
is, you place your "home/.bashrc"
-
it's just a file that is kind
of a special file in UNIX,
-
that says oh, whenever you want to read
this file go to this other file.
-
There's no content, like there is no...
-
your aliases are not part of this dotfile. That file
is just kind of like a pointer, saying now you should
-
go that other way.
-
And by doing that you can have your other file
-
in that other folder.
-
If version controlling is not useful, think about
-
what if you want to have them in your Dropbox
folder, so they're synced to the cloud,
-
for example. That's kind of another use case
where like symlinks could be really useful
-
So you don't need the folder dotfiles
to be in the home directory, right?
-
Because you can just use the symlink,
that points somewhere else.
-
As long as you have a way for the default path
to resolve wherever you have it, yeah.
-
Last thing I want to cover in the lecture...
-
Oh, sorry, any other questions about dotfiles?
-
Last thing I want to cover in the lecture
is working with remote machines,
-
which is a thing that you will run into,
-
sooner or later.
-
And there are a few things that will make your life
much easier when dealing with remote machines
-
if you know about them.
-
Right now maybe because you are
using the Athena cluster,
-
but later on, during your programming career,
-
it's pretty sure that
-
there is a fairly ubiquitous
concept of having your
-
local working environment and then having some
production server that is actually running the
-
code, so it is really good to get familiar
-
about how to work in/with remote machines.
-
So the main command for working
with remote machines is SSH.
-
SSH is just like a secure shell, it's
just gonna take the responsibility for
-
reaching wherever we want or tell it to go
-
and trying to open a session there.
-
So here the syntax is:
-
"JJGO" is the user that I want
to use in the remote machine,
-
and this is because the user is
-
different from the one I have my local machine,
which will be the case a lot of the time,
-
then the "@" is telling the
terminal that this separates
-
what the user is from what the address is.
-
And here I'm using an IP address because
what I'm actually doing is
-
I have a virtual machine in my computer,
-
that is the one that is remote right now.
-
And I'm gonna be SSH'ing into it. This is the
-
URL that I'm using,
-
sorry, the IP that I'm using,
-
but you might also see things like
-
oh I want to SSH as "JJGO"
-
at "foobar.mit.edu"
-
That's probably something more
common, if you are using some
-
remote server that has a DNS name.
-
So going back to a regular command,
-
we try to SSH, it asks us for a password,
-
really common thing.
-
And now we're there. We have...
-
we're still in our same terminal emulator
-
but right now SSH is kind of forwarding the
entire virtual display to display what the
-
remote shell is displaying. And
we can execute commands here and
-
we'll see the remote files
-
A couple of handy things to know about
SSH, that were briefly covered in the
-
data wrangling lecture, is that
SSH is not only good for just
-
opening connections. It will also let
you just execute commands remotely.
-
So for example, if I do that, it's gonna ask me
-
what is my password?, again.
-
And it's executing this command
-
then coming back to my terminal
-
and piping the output of what that
command was, in the remote machine,
-
through the standard output in my current cell.
-
And I could have this in...
-
I could have this in a pipe, and
-
this will work and we'll just
-
drop all this output and then have a local pipe
-
where I can keep working.
-
So far, it has been kind of inconvenient,
having to type our password.
-
There's one really good trick for this.
-
It's we can use something called "SSH keys".
-
SSH keys just use public key encryption
-
to create a pair of SSH keys, a public
key and a private key, and then
-
you can give the server the
public part of the key.
-
So you copy the public key and
then whenever you try to
-
authenticate instead of using your password,
it's gonna use the private key to
-
prove to the server that you are
actually who you say you are.
-
We can quickly showcase how you will go
-
about doing this.
-
Right now I don't have any SSH keys,
so I'm gonna create a couple of them.
-
First thing, it's just gonna ask
me where I want this key to live.
-
Unsurprisingly, it's doing this.
-
This is my home folder and then
it's using this ".ssh" path,
-
which refers back to the same concept
that we covered earlier about having
-
dotfiles. Like ".ssh" is a folder
that contains a lot of the
-
configuration files for how
you want SSH to behave.
-
So it will ask us a passphrase.
-
The passphrase is to encrypt
the private part of the key
-
because if someone gets your private key,
if you don't have a password protected
-
private key, if they get that key
-
they can use that key to impersonate
you in any server.
-
Whereas if you add a passphrase,
-
they will have to know what the passphrase
is to actually use the key.
-
It has created a keeper. We can check that
these two files are now under ssh.
-
And we can see...
-
We have these two files: we have
the 25519 and the public key.
-
And if we "cat" through the output,
-
that key is actually not like
any fancy binary file, it's
-
just a text file that has the contents
of the public key and some
-
alias name for it, so we can
know what this public key is.
-
The way we can tell the server that
we're authorized to SSH there
-
is by just actually copying this file,
like copying this string into a file,
-
that is ".ssh/authorized_keys".
-
So here what I'm doing is I'm
-
catting the output of this file
-
which is just this line of
text that we want to copy
-
and I'm piping that into SSH and then remotely
-
I'm asking "tee" to dump the contents
of the standard input
-
into ".ssh/authorized_keys".
-
And if we do that, obviously it's
gonna ask us for a password.
-
It was copied, and now we
can check that if we try
-
to SSH again,
-
It's going to first ask us for a passphrase
-
but you can arrange that so that
it's saved in the session
-
and we didn't actually have to
type the key for the server.
-
And I can kind of show that again.
-
More things that are useful.
-
Oh, we can do...
-
If that command seemed a little bit janky,
-
you can actually use this command
that is built for this,
-
so you don't have to kind of
craft this "ssh tee" command.
-
That is just called "ssh-copy-id".
-
And we can do the same
-
and it's gonna copy the key.
-
And now, if we try to SSH,
-
we can SSH without actually
typing any key at all,
-
or any password.
-
More things.
-
We will probably want to copy files.
-
You cannot use "CP"
-
but you can use "SCP", for "SSH copy".
-
And here we can specify that we want
to copy this local file called notes
-
and the syntax is kind of similar.
-
We want to copy to this remote and
-
then we have a semicolon to separate
what the path is going to be.
-
And then we have
-
oh, we want to copy this as notes
-
but we could also copy this as foobar.
-
And if we do that, it has been executed
-
and it's telling us that all the
contents have been copied there.
-
If you're gonna be copying a lot of files,
-
there is a better command
that you should be using
-
that is called "RSYNC". For example, here
-
just by specifying these three flags,
-
I'm telling RSYNC to kind of preserve
all the permissions whenever possible
-
to try to check if the file
has already been copied.
-
For example, SCP will try to copy
files that are already there.
-
This will happen for example
if you are trying to copy
-
and the connection interrupts
in the middle of it.
-
SCP will start from the very beginning,
trying to copy every file,
-
whereas RSYNC will continue
from where it stopped.
-
And here,
-
we ask it to copy the entire folder and
-
it's just really quickly
copied the entire folder.
-
One of the other things to know about SSH is that
-
the equivalent of the dot file
for SSH is the "SSH config".
-
So if we edit the SSH config to be
-
If I edit the SSH config to
look something like this,
-
instead of having to, every
time, type "ssh jjgo",
-
having this really long string so I can
like refer to this specific remote,
-
I want to refer, with the specific user name,
-
I can have something here that says
-
this is the username, this
is the host name, that this
-
host is referring to and you should
use this identity file.
-
And if I copy this,
-
this is right now in my local folder,
-
I can copy this into ssh.
-
Now, instead of having to do this really
long command, I can just say
-
I just want to SSH into the host called VM.
-
And by doing that, it's grabbing all that
configuration from the SSH config
-
and applying it here.
-
This solution is much better than something
like creating an alias for SSH,
-
because other programs like SCP and RSYNC
-
also know about the dotfiles for SSH and
will use them whenever they are there.
-
Last thing I want to cover about remote machines is
that here, for example, we'll have tmux and we can,
-
like I was saying before, we
can start editing some file
-
and we can start running some job.
-
For example, something like HTOP.
-
And this is running here, we can
-
detach from it,
-
close the connection and
-
then SSH back. And then, if you do "tmux a",
-
everything is as you left it, like
nothing has really changed.
-
And if you have things executing there in
the background, they will keep executing.
-
I think that, pretty much, ends
all I have to say for this tool.
-
Any questions related to remote machines?
-
That's a really good question.
So what I do for that,
-
Oh, yes, sorry.
-
So the question is, how do you deal with
trying to use tmux in your local machine,
-
and also trying to use tmux
in the remote machine?
-
There are a couple of tricks
for dealing with that.
-
The first one is changing the prefix.
-
So what I do, for example, is
-
in my local machine the prefix I have
changed from "Ctrl+B" to "Ctrl+A" and
-
then in remove machines this is still "Ctrl+B".
-
So I can kind of swap between,
-
if I want to do things to the
local tmux I will do "Ctrl+A"
-
and if I want to do things to the
remote tmux I would do "Ctrl+B".
-
Another thing is that you
can have separate configs,
-
so I can do something like this, and then...
-
Ah, because I don't have my own ssh config, yeah.
-
But if you...
-
Um, I can SSH "VM".
-
Here, what you see,
-
the difference between these
two bars, for example,
-
is because the tmux config is different.
-
As you will see in the exercises,
the tmux configuration is in
-
the tmux.conf
-
And in tmux.conf,
-
here you can do a lot of things like changing
the color depending on the host you are
-
so you can get like quick visual
feedback about where you are, or
-
if you have a nested session. Also, tmux will,
-
if you're in the same host and you
try to tmux within a tmux session,
-
it will kind of prevent you from doing
it so you don't run into issues.
-
Any other questions related, to kind
of all the topics we have covered.
-
Another answer to that question is
also, if you type the prefix twice,
-
it sends it once to the underlying shell.
-
So the local binding is "Ctrl+A" and
the remote binding is "Ctrl+A",
-
You could type "Ctrl+A", "Ctrl+A" and then "D", for
example, detaches from the remote, basically.
-
I think that ends the class for today, there's a bunch
of exercises related to all these main topics and
-
we're gonna be holding office hours today, too.
So feel free to come and ask us any questions.