Wednesday, April 22, 2015

Day 19: The Linux Command Line Ch16 Notes


Chapter 16 - Networking

Commands:
ping - Send an ICMP ECHO_REQUEST to network hosts
traceroute - Print the route packets trace to a network host
netstat - Print network connections, routing tables, interface statistics, masquerade connections, and multicast memberships
host - DNS lookup utility
ftp - Internet file transfer program
wget - Non-interactive network downloader
ssh - OpenSSH SSH client (remote login program)

First a little terminology (explanation for 13 year old son):

IP Address: An address that identifies a device in the network.
Just like most people have home addresses, computers and other devices in the network (printers, routers, switches, smart TVs, etc.). In order to send messages between those devices computer-to-computer talk, they must have some form of unique identifiers. They are those four bytes that look like:
192.168.1.1

Host: computer in the network
Computer can have many applications installed on them. The ones that want to communicate accross the network. For instance, your game, your web browser etc. We say that computers are hosts for this applications.

Domain Name: Name that represents IP address
Since applications require IP addresses of the servers (server is a bigger computer that sends to your application what it requested), with which it communicate, it would be next to impossible for you to remember those four-byte thingies. Instead, you use names rather than addresses, but there is a special service on the Internet that translates them to actual IP addresses that your computer can use. For instance, in your web browser you say:
http://www.raspberrypi.org, rather than, http://93.93.130.39. 

In this post I would like to help you get the hang of networking basics.

On the command line type:

$ ping 8.8.8.8

After few seconds press CTRL-c to stop it.

Here's my output of this test:

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=23.8 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=57 time=24.5 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=57 time=24.6 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=57 time=33.3 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=57 time=25.7 ms
64 bytes from 8.8.8.8: icmp_seq=6 ttl=57 time=25.4 ms
^C
--- 8.8.8.8 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5009ms
rtt min/avg/max/mdev = 23.858/26.278/33.336/3.218 ms

What just happened?
Your computer sent a number of special packets called: ICMP echo-request (will talk more on ICMP some time in the future). Those messages were delivered by so called routers (special devices finding the best path to destinations and forwarding those packets to them), to a computer with IP address 8.8.8.8. That happens to be Google public DNS server (the one that can translate any domain name to actual IP address).

Since the computer 8.8.8.8 responded with ICMP echo-reply message (those line you see above starting with 64 bytes from 8.8.8.8), it shows you that your computer has access to the Internet. Also, you can learn that the average time it took to send this packet and receive reply from 8.8.8.8 host is 26.278 millisecond). Pow Wow! That's fast right? (millisecond is one millionth of a second!).

If you want to send a specified number of packets (say 4 packets only), try to use the following command:

$ ping -c 4 8.8.8.8

Next, very useful tool to check what routers (those magical boxes delivering our packets to the right host in different network than ours), are between us and the final destination. Try this (if you don't have this command available on your RP, do this: $ sudo apt-get update; sudo apt-get install traceroute):

$ traceroute 8.8.8.8

Today, I am in the hotel in town called Tralee, Ireland. This is what I got:

traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
 1  10.16.0.254 (10.16.0.254)  7.131 ms  7.100 ms  7.084 ms
 2  86-45-112-3-dynamic.agg9.chf.chf-qkr.eircom.net (86.45.112.3)  113.396 ms  117.233 ms  117.241 ms
 3  lag-24.pe1.rtd.rsl-rtd.eircom.net (86.43.13.69)  27.189 ms  27.196 ms  27.182 ms
 4  * * *
 5  lag-50.br1.6cr.border.eircom.net (86.47.63.112)  33.020 ms  33.010 ms  32.999 ms
 6  inex.google.com (193.242.111.57)  32.986 ms  22.912 ms  22.873 ms
 7  209.85.250.213 (209.85.250.213)  22.829 ms 66.249.95.91 (66.249.95.91)  22.646 ms 209.85.250.215 (209.85.250.215)  22.578 ms
 8  google-public-dns-a.google.com (8.8.8.8)  24.808 ms  24.779 ms  24.738 ms

The number 4 (asterisks) did not respond to my request, but all other did. It seems like there are 7 routers between my laptop and host 8.8.8.8 which is the last responder. There IP addresses or names are displayed. If you want only IP addresses, disable domain name resolution doing this:

$ traceroute -n 8.8.8.8

Here's my output:

traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
 1  10.16.0.254  5.435 ms  5.381 ms  5.330 ms
 2  86.45.112.3  20.936 ms  23.475 ms  23.442 ms
 3  86.43.13.69  20.793 ms  20.741 ms  23.283 ms
 4  86.43.253.9  26.518 ms  26.531 ms  26.483 ms
 5  * * *
 6  193.242.111.57  26.267 ms  24.507 ms  24.423 ms
 7  209.85.250.213  27.151 ms 66.249.95.135  23.204 ms 209.85.250.213  23.177 ms
 8  8.8.8.8  23.154 ms  23.527 ms  23.479 ms

This time it is the 5th router that did not respond in timely manner. Cool!

One last networking command I'd like you to play with today (more on networking tomorrow), is netstat.

Do this:

$ netstat -r

Here's my output (Hotel in Tralee)

Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
default         10.16.0.254     0.0.0.0         UG        0 0          0 wlan0
10.16.0.0       *               255.255.255.0   U         0 0          0 wlan0

I can find out that my default gateway (local router that will be helping my packets find the destinations) is 10.16.0.254.

If you want to see some statistics of your interface try this:

$ netstat -ie

It displays statistics of all network interfaces of your computer (again my laptop in the hotel shows something like this):

wlan0     Link encap:Ethernet  HWaddr 00:24:d6:75:7e:40  
          inet addr:10.16.0.137  Bcast:10.16.0.255  Mask:255.255.255.0
          inet6 addr: fe80::224:d6ff:fe75:7e40/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:22154 errors:0 dropped:0 overruns:0 frame:0
          TX packets:16542 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 

          RX bytes:17330515 (17.3 MB)  TX bytes:3320213 (3.3 MB)

Received 17.3 MB so far. Transmitted 3.3 MB, no errors etc.

These tools have a way more to offer than I showed you. One thing at a time ;).

Before we call it a day, I am going to add one more tool so you can find out if your domain name service is working. This service is the most important service we have on the Internet. Remember that you use domain names in your applications rather than IP addresses? Who would remember all those weird numbers. It is so much easier to remember: minecraft.net rather than its current IP address.

Check this out:

$ host minecraft.net

Here's my output:

minecraft.net has address 54.243.72.162

BEAUTIFUL!

Mess around with those commands. Try to see man pages of the ones we used today. Some of them have a huge number of options, so don't try to remember them. Instead, read as much as you can to have an idea of their capabilities. You can always come back to those specifics.

More on networking in the next post. Meanwhile have fun with our today's tools.

What do you think this command do?

$ host minecraft.net 8.8.8.8

It also resolves name-to-ip but instead of using your local DNS server, it will ask Google public DNS server for help to resolve the name!



PS. Some workers cut the phone line to my house I'm told. Next post in few days when Eircom fixes it. So far they did not say when ..., that's just great. No Internet for God knows how many days! 

Tuesday, April 21, 2015

Day 18: Installation of Raspbian Step By Step (instead of ch15)


Chapter 15 - Storage Media


DON'T READ CHAPTER 15 (13 year old using RP doesn't need this skill yet). Instead, learn how to download, check integrity and install Raspbian on your Raspberry PI.


Commands:
mount – Mount a file system
umount – Unmount a file system
fsck – Check and repair a file system
fdisk – Partition table manipulator
mkfs – Create a file system
fdformat – Format a floppy disk
dd – Write block oriented data directly to a device
genisoimage (mkisofs) – Create an ISO 9660 image file
wodim (cdrecord) – Write data to optical storage media

md5sum – Calculate an MD5 checksum

Here are the step-by-step instructions:


  1. Download the zip file containing the image from a mirror or torrent
  2. Verify if the the hash key of the zip file is the same as shown on the downloads page (optional). Assuming that you put the zip file in your home directory (~/), in the terminal run:
    • sha1sum ~/2012-12-16-wheezy-raspbian.zip
    • This will print out a long hex number which should match the "SHA-1" line for the SD image you have downloaded
  3. Extract the image, with
    • unzip ~/2012-12-16-wheezy-raspbian.zip
  4. Run df -h to see what devices are currently mounted
  5. If your computer has a slot for SD cards, insert the card. If not, insert the card into an SD card reader, then connect the reader to your computer.
  6. Run df -h again. The device that wasn't there last time is your SD card. The left column gives the device name of your SD card. It will be listed as something like "/dev/mmcblk0p1" or "/dev/sdd1". The last part ("p1" or "1" respectively) is the partition number, but you want to write to the whole SD card, not just one partition, so you need to remove that part from the name (getting for example "/dev/mmcblk0" or "/dev/sdd") as the device for the whole SD card. Note that the SD card can show up more than once in the output of df: in fact it will if you have previously written a Raspberry Pi image to this SD card, because the Raspberry Pi SD images have more than one partition.
  7. Now that you've noted what the device name is, you need to unmount it so that files can't be read or written to the SD card while you are copying over the SD image. So run the command below, replacing "/dev/sdd1" with whatever your SD card's device name is (including the partition number)
    • umount /dev/sdd1
    • If your SD card shows up more than once in the output of df due to having multiple partitions on the SD card, you should unmount all of these partitions.
  8. In the terminal write the image to the card with this command, making sure you replace the input file if= argument with the path to your .img file, and the "/dev/sdd" in the output file of= argument with the right device name (this is very important: you will lose all data on the hard drive on your computer if you get the wrong device name). Make sure the device name is the name of the whole SD card as described above, not just a partition of it (for example, sdd, not sdds1 or sddp1, or mmcblk0 not mmcblk0p1)
    • dd bs=4M if=~/2012-12-16-wheezy-raspbian.img of=/dev/sdd
      • Please note that block size set to 4M will work most of the time, if not, please try 1M, although 1M will take considerably longer.
    • Note that if you are not logged in as root you will need to prefix this with sudo
    • The dd command does not give any information of its progress and so may appear to have frozen. It could take more than five minutes to finish writing to the card. If your card reader has an LED it may blink during the write process. To see the progress of the copy operation you can run pkill -USR1 -n -x dd in another terminal (prefixed with sudo if you are not logged in as root). The progress will be displayed (perhaps not immediately, due to buffering) in the original window, not the window with the pkill command.
  9. Instead of dd you can use dcfldd; it will give a progress report about how much has been written.
  10. You can check what's written to the SD card by dd-ing from the card back to your harddisk to another image, and then running diff (or md5sum) on those two images. There should be no difference.
  11. As root run the command sync or if a normal user run sudo sync (this will ensure the write cache is flushed and that it is safe to unmount your SD card)
  12. Remove SD card from card reader, insert it in the Raspberry Pi, and have fun



Monday, April 20, 2015

Day 17: The Linux Command Line Ch14 Notes


Chapter 14 - Package Management

All the question will be related to debian-style Linux (I use Raspbian OS here).


Question 1
What is debian-style low-level packaging tool?

Question 2
What is debian-style high-level packaging tool?

Question 3
How to find a particular package using package name?

Question 4
How to verify details of vsftpd server?

Question 5
How to install vsftpd server?

Question 6
How to remove a package from a system?

Question 7
How update packages using one line?

Question 8
How to list installed packages?

Question 9
How to determine that vim editor is installed on the system?

Question 10 (not included in the TLCL book)
How to check the list of installed files using the name of the package?

Question 11 (not included in the TLCL book)
How to determine which package installed a specific file (for instance /etc/host.conf)?



Answers

Question 1
What is debian-style low-level packaging tool?

dpkg

Question 2
What is debian-style high-level packaging tool?

apt-get or aptitude

Question 3
How to find a particular package using package name?

$ sudo apt-get update
$ sudo apt-cache search search_string

Example:
$ sudo apt-cache search vsftpd

Question 4
How to verify details of vsftpd server?

$ sudo apt-cache show vsftpd

Question 5
How to install vsftpd server?

$ sudo apt-get udpate
$ sudo apt-get install vsftpd

Question 6
How to remove a package from a system?

$ sudo apt-get remove package_name

Question 7
How update packages using one line?

$ sudo apt-get update; sudo apt-get upgrade

Question 8
How to list installed packages?

$ dpkg-query -l

or

$ dpkg --get-selections

Question 9
How to determine that vim editor is installed on the system?

$ dpkg --status vim

Question 10 (not included in the TLCL book)
How to check the list of installed files using the name of the package?

$ dpgk -L

Question 11 (not included in the TLCL book)
How to determine which package installed a specific file (for instance /etc/host.conf)?


$ dpkg -S /etc/hosts.conf



Sunday, April 19, 2015

Day 16: The Linux Command Line Ch13 Notes


Chapter 13 - Customizing The Prompt

The command: 'echo $PS1' on my Raspberry PI reveals the following:



Changing the look of the prompt may be an interesting way of making your Raspberry Pi your own!

Things I want to remember:

\u@\h
user@host

\w
name of current working directory

\[
start of one or more non-printing characters (such as colors)

\]
end of one or more non-printing characters (such as colors)

033
ANSI code for ESC key followed by option and attribute (look below)

The below tables are only for reference (no need to memorize them).


Escape Sequences Used To Set Text Color



Escape Sequences Used To Set Background Color



Cursor Movement Escape Sequences



Lab 7

1. Change the prompt of your RP so it shows starts with $ followed by a space.
2. Make sure that that this new prompt can survive reboot.


Lab 7 Solution

1. Change the prompt of your RP so it shows starts with $ followed by a space.

$ PS1="$ "

2. Make sure that that this new prompt can survive reboot.

Edit .bashrc file and add:
PS1="$ "



Day 15: The Linux Command Line Ch12 Notes


Chapter 12 - Gentle Introduction To VIM

I have been using VIM for many years and I love this arcane text editor for its power. However, the beginnings are quite difficult. If you decide that even though it is arduous to learn VIM you want it to do it, keep on reading chapter 12 of "The Linux Command Line". Once you have done it, here is the basic list of commands you can use in VIM (more options to configure VIM in Day 3 post).

VIM Most Commonly Used Options:

Insert mode - inserting/appending text

i - insert before the cursor
I - insert at the beginning of the line
a - insert (append) after the cursor
A - insert (append) at the end of the line
o - append (open) a new line below the current line
O - append (open) a new line above the current line
ea - insert (append) at the end of the word
Esc - exit insert mode

Cursor movement

h - move cursor left
j - move cursor down
k - move cursor up
l - move cursor right
w - jump forwards to the start of a word
W - jump forwards to the start of a word (words can contain punctuation)
e - jump forwards to the end of a word
E - jump forwards to the end of a word (words can contain punctuation)
b - jump backwards to the start of a word
B - jump backwards to the start of a word (words can contain punctuation)
0 - jump to the start of the line
^ - jump to the first non-blank character of the line
$ - jump to the end of the line
G - go to the last line of the document
5G - go to line 5

Editing
r - replace a single character
J - join line below to the current one
cc - change (replace) entire line
cw - change (replace) to the end of the word
c$ - change (replace) to the end of the line
s - delete character and substitute text
S - delete line and substitute text (same as cc)
xp - transpose two letters (delete and paste)
u - undo
Ctrl + r - redo
. - repeat last command

Marking text (visual mode)

v - start visual mode, mark lines, then do a command (like y-yank)
V - start linewise visual mode
o - move to other end of marked area
Ctrl + v - start visual block mode
O - move to other corner of block
aw - mark a word
ab - a block with ()
aB - a block with {}
ib - inner block with ()
iB - inner block with {}
Esc - exit visual mode

Cut and paste

yy - yank (copy) a line
2yy - yank (copy) 2 lines
yw - yank (copy) word
y$ - yank (copy) to end of line
p - put (paste) the clipboard after cursor
P - put (paste) before cursor
dd - delete (cut) a line
2dd - delete (cut) 2 lines
dw - delete (cut) word
D - delete (cut) to the end of the line
d$ - delete (cut) to the end of the line
x - delete (cut) character

Exiting

:w - write (save) the file, but don't exit
:wq or :x or ZZ - write (save) and quit
:q - quit (fails if there are unsaved changes)
:q! or ZQ - quit and throw away unsaved changes
:xa - save and quit all split windows (buffers)

Marking text (visual mode)
v - start visual mode, mark lines, then do a command (like y-yank)
V - start linewise visual mode
o - move to other end of marked area
Ctrl + v - start visual block mode
O - move to other corner of block
aw - mark a word
ab - a block with ()
aB - a block with {}
ib - inner block with ()
iB - inner block with {}
Esc - exit visual mode

Visual commands

> - shift text right
< - shift text left
y - yank (copy) marked text
d - delete marked text
~ - switch case

Search and replace
/pattern - search for pattern
?pattern - search backward for pattern
n - repeat search in same direction
N - repeat search in opposite direction
:%s/old/new/g - replace all old with new throughout file
:%s/old/new/gc - replace all old with new throughout file with confirmations

Working with multiple files

:e filename - edit a file in a new buffer
:bnext or :bn - go to the next buffer
:bprev or :bp - go to the previous buffer
:bd - delete a buffer (close a file)
:sp filename - open a file in a new buffer and split window
:vsp filename - open a file in a new buffer and vertically split window
Ctrl + ws - split window
Ctrl + ww - switch windows
Ctrl + wq - quit a window
Ctrl + wv - split window vertically
Ctrl + wh - move cursor to next buffer (right)
Ctrl + wl - move cursor to previous buffer (left)

Tabs

:tabnew filename or :tabn filename - open a file in a new tab
Ctrl + wt - move the current split window into its own tab
gt or :tabnext or :tabn - move to the next tab
gT or :tabprev or :tabp - move to the previous tab
#gt - move to tab number #
:tabmove # - move current tab to the #th position (indexed from 0)
:tabclose or :tabc - close the current tab and all its windows
:tabonly or :tabo - close all tabs except for the current one


Saturday, April 18, 2015

Day 14: The Linux Command Line Ch11 Notes


Chapter 11 - The Environment

Commands:
printenv – Print part or all of the environment
set – Set shell options
export – Export environment to subsequently executed programs
alias – Create an alias for a command

Most programs running will use their respective configuration files. Some of them will adjust their behavior using shell variables and environment variables.


Question 1
What does 'set | less' command do?

Question 2
What does 'printenv' command do?

Question 3
Which command can you use to display variable PATH that stores path to executable programs?

Question 4
What is a login shell session?

Question 5
What is a non-login session?

Question 6
Which login session files can Linux read to establish environment?

Question 7
Which startup files a non-login session reads?

Question 8
Which command can you use to display hidden startup files?

Question 9
What does 'export' command do?



ANSWERS

Question 1
What does 'set | less' command do?

It displays both shell and environment variables.

Question 2
What does 'printenv' command do?

It displays only environment variables.

Question 3
Which command can you use to display variable PATH that stores path to executable programs?

$ echo $PATH

or

$ printenv PATH

Question 4
What is a login shell session"?

It is session that prompts us for username and password.

Question 5
What is a non-login session?

It is a terminal session we open from GUI.

Question 6
Which login session files can Linux read to establish environment?

/etc/profile
Script applied to all users

~/.bash_profile
User's personal startup file which can extend or override global configuraition script

~/.bash_login
If ~/.bash_profile is not found, bash will attempt to read this script

~/.profile
If neither of the two previous is found, bash attempts to read this file (debian-based default)


Question 7
Which startup files a non-login session reads?

/etc/bash.bashrc
Global configuration script applied to all users

~/.bashrc
User's personal startup file. It can extend or override global script.

Question 8
Which command can you use to display hidden startup files?

$ ls -a

or 

$ ls -A

Question 9
What does 'export' command do?

Once changes are made in the parent shell, child does not inherit those by default. The command 'export' will allow child shell originated from parent shell to recognize all variable changes.


LAB 6

1. Check the name of your display (number 0 indicates the first display generated by X server). If you're connected via ssh nothing shows.

2. Check the name of your shell program.

3. Check the path to your home directory.

4. Check your terminal type.


LAB ANSWERS

1. Check the name of your display (number 0 indicates the first display generated by X server). If you're connected via ssh nothing shows.

$ printenv DISPLAY

2. Check the name of your shell program.

$ printenv SHELL

3. Check the path to your home directory.

$ printenv HOME

4. Check your terminal type.

$ printenv TERM

Good stuff!


Friday, April 17, 2015

Day 13: The Linux Command Line Ch10 Notes Cont


Chapter 10 - Processes Continued

Commands:
ps – Report a snapshot of current processes
top – Display tasks
jobs – List active jobs
bg – Place a job in the background
fg – Place a job in the foreground
kill – Send a signal to a process
killall – Kill processes by name
shutdown – Shutdown or reboot the system

Controlling Processes

CTRL-c
Interrupt process (many programs are ask to be terminated, but not all will terminate). 

&
Starting program followed by "&" puts the process in the background (making it hidden). This way we can work on the console while program is working for us in the background. 

$ jobs
Displays IDs of programs running in the background

$ fg %number 
(where number is job id)
Brings the process back to forground making it visible.

CTRL-z
Pauses the program. Program that is paused can be put in the forground using 'fg %number' or into background using 'bg %number'

$ bg %number
Places process in the background making it invisible.

Signals

The 'kill' command sends signals to program (TERM signal is send by default). The syntax is as shown below:

$ kill [-signal] PID

where PID is process id (check with ps aux or ps -e)
and signal is one of the following:




Wednesday, April 15, 2015

Day 12: The Linux Command Line Ch10 Notes


Chapter 10 - Processes

Commands:
ps – Report a snapshot of current processes
top – Display tasks
jobs – List active jobs
bg – Place a job in the background
fg – Place a job in the foreground
kill – Send a signal to a process
killall – Kill processes by name
shutdown – Shutdown or reboot the system

Question 1
Given the following output:




Answer the following:
a) What is the process id?
b) How long ago did the process start?
c) What is the percentage of that the process uses?
d) How many kilobytes of physical memory does the process use?

Question 2
Which command does display processes continuously and how to stop it ?

Answers

Answer the following:
a) What is the process id?

1226

b) How long ago did the process start?

19 hours and 19 minutes

c) What is the percentage of that the process uses?

0.0%

d) How many kilobytes of physical memory does the process use?

1020 kB

Question 2
Which command does display processes continuously and how to stop it ?

$ top 
$ q


Lab 5

1. Start nano text editor from the command line. In nano write: "Raspberry is Cool."
2. Pause nano by putting it to the background (do not terminate it).
3. Start another nano text editor from the command line. In this copy of nano write: "Inline skating is cool."
4. Pause nano by putting it to the background (do not terminate it).
5. Display the jobs put to the background.
6. Bring the first nano to the foreground (you should see the line: "Raspberry is Cool."
7. Put this process to background again.
8. Bring the second instance of nano to the foreground (you should 
9. Put this process to the background again.
10. Display the processes running by this terminal
11. Bring first nano to the foreground and exit without saving the text, then CTRL-x and don't save the file
12. Bring first nano to the foreground and exit without saving the text, then CTRL-x and don't save the file

Lab 5 Solutions

1. Start nano text editor from the command line. In nano write: "Raspberry is Cool."

$ nano

2. Pause nano by putting it to the background (do not terminate it).

$ CTRL-z

3. Start another nano text editor from the command line. In this copy of nano write: "Inline skating is cool."

$ nano

4. Pause nano by putting it to the background (do not terminate it).

$ CTRL-z

5. Display the jobs put to the background.

$ jobs

6. Bring the first nano to the foreground (you should see the line: "Raspberry is Cool."

$ fg %1

7. Put this process to background again.

$ CTRL-z

8. Bring the second instance of nano to the foreground (you should see the line: "Inline skating is cool."

$ fg %2

9. Put this process to the background again.

$ CTRL-z

10. Display the processes running by this terminal

$ ps

11. Bring first nano to the foreground and exit without saving the text.

$ fg %1
then CTRL-x and don't save the file

12. Bring first nano to the foreground and exit without saving the text.

$ fg %2
then CTRL-x and don't save the file