The below are parsed from the same code that generated the lecture slides. The material on this page in no way is a replacement for reading through the full slides, as it only contains excerpts and potentially lacks relevant context. That said, there’s little reason for you to need to hunt through the slides when you just want a refresher on how something works / what commands you learned when.
ssh <username>@remote
-
username
is the username on the remote host. -
remote
is the url of the server you want to log into.-
IP Address, e.g.,
128.253.141.34
-
Symbolic name, e.g.,
wash.cs.cornell.edu
-
IP Address, e.g.,
-
Use
@
to specify username.-
ssh username@remote
-
-
On
wash
I ammpm288
:-
v1:
ssh mpm288@128.253.3.197
-
v2:
ssh mpm288@wash.cs.cornell.edu
- ( or fill in the fields if you’re using a graphical SSH client)
-
(if you need the port number, it’s
22
)
-
v1:
man command_name
- Loads the manual (manpage) for the specified command.
-
Unlike google, manpages are
system-specific
. - Usually very comprehensive. Sometimes too comprehensive.
-
Type
/keyword
to search forkeyword
, and hit<enter>
. -
The
n
key jumps to the next search result.
Flags and Options: Formats
-
A flag that is
-
One letter is specified with a single dash (
-a
). -
More than one letter is specified with two dashes (
--all
). - The reason is because of how switches can be combined.
-
One letter is specified with a single dash (
-
We generally use “flag” and “switch” interchangeably:
- “flag” the command, telling it that “action X” should occur
- specify to the command to “switch on/off action X”
Flags and Options: Switches
- Switches take no arguments, and can be specified in a couple of different ways.
- Switches are usually one letter, and multiple letter switches usually have a one letter alias.
-
One option:
-
ls -a
-
ls --all
-
-
Two options:
-
ls -l -Q
-
ls -lQ
-
-
Usually
applied from left to right in terms of operator precedence, but not always:
- This is up to the developer of the tool.
-
Prompts:
rm -fi <file>
-
Does
not
prompt:
rm -if <file>
Flags and Options: Argument Specifiers
-
The
--argument="value"
format, where the=
and quotes are needed ifvalue
is more than one word.-
Yes:
ls --hide="Desktop" ~/
-
Yes:
ls --hide=Desktop ~/
- One word, no quotes necessary
-
No:
ls --hide = "Desktop" ~/
-
Spaces by the
=
will be misinterpreted -
It used
=
as the argument tohide
-
Spaces by the
-
Yes:
-
The
--argument value
format (space after theargument
).- Quote rules same as above.
-
ls --hide "Desktop" ~/
-
ls --hide Desktop ~/
-
Usually,
--argument value
and--argument=value
are interchangeable.- Not always!
groups [user name]
- Lists groups to which [argument] belongs.
- With no argument, lists your groups
chmod <mode> <file>
-
Changes file or directory permissions to
<mode>
. -
The format of
<mode>
is a combination of three fields:-
Who is affected: a combination of
u
,g
,o
, ora
(all). -
Use a
+
to add permissions, and a-
to remove. -
Specify type of permission: any combination of
r
,w
,x
.# Add read, write, & execute for user, group, & other $ chmod ugo+rwx <file> # or chmod a+rwx <file> # Remove read and write for other $ chmod o-rw <file>
-
Who is affected: a combination of
-
Can specify mode in octal: user, then group, then other.
-
E.g.,
750
meansuser=7
,group=5
,other=0
permissions.
-
E.g.,
chgrp group <file>
-
Changes the group ownership of
<file>
togroup
. -
The
-R
flag will recursively change permissions of a directory.
chown user:group <file>
-
Changes the ownership of
<file>
. -
The
group
is optional (chown user <file>
). -
The
-R
flag will recursively change permissions of a directory.
stat [opts] <filename>
- Gives you a wealth of useful information.
-
Uid
(%U
) is the user,Gid
(%G
) is the group.-
BSD/OSX:
stat -x <filename>
for “standard” behavior.
-
BSD/OSX:
-
Can be useful to mimic file permissions you don’t know.
-
Human readable:
--format=%A
, e.g.-rw-rw-r--
-
BSD/OSX:
-f %Sp
is used instead.
-
BSD/OSX:
-
Octal:
--format=%a
(great forchmod
), e.g.664
-
BSD/OSX:
-f %A
is used instead.
-
BSD/OSX:
-
Human readable:
umask <mode>
-
Remove
mode
from the file’s permissions. -
Similar syntax to
chmod
:-
umask 077
:+rwx
for owner ,-
for all others. -
umask g+w
: enables group write permissions.
-
-
umask -S
: display the current mask. -
Just a bit mask with
0o777
and your mode .Full permissions 0o777
Sample User Mask 0o002
Logical &
Gives0o002
more <filename>
- Scroll through one page at a time.
- Program exits when end is reached.
less <filename>
- Scroll pages or lines (mouse wheel, space bar, and arrows).
- Program does not exit when end is reached.
head -[numlines] <filename>
tail -[numlines] <filename>
-
Prints the first / last
numlines
of the file. -
First 5 lines:
head -5 file.txt
orhead -n5 file.txt
-
Last 5 lines:
tail -5 file.txt
ortail -n5 file.txt
- Default is 10 lines.
echo <text>
- Prints the input string to the standard output (the terminal).
-
We will soon learn how to use
echo
to put things into files, append to files, etc. -
Show off to your friends how cool you are:
$ echo 'I can have a conversation with my computer!' $ echo 'But it always copies me. RUDE.'
man command_name
- Loads the manual (manpage) for the specified command.
-
Unlike google, manpages are
system-specific
. - Usually very comprehensive. Sometimes too comprehensive.
-
Type
/keyword
to search forkeyword
, and hit<enter>
. -
The
n
key jumps to the next search result.
File Ownership
-
You can discern who owns a file many ways, the most immediate being
ls -l
Permissions with ls
$ ls -l README -rwxrw---- 1 milano cs2043tas 20 Jan 26 15:48 README # milano <-- the user # cs2043tas <-- the group
- Third column is the user , fourth column is the group .
-
Other columns are the
link count
and
size
- we’ll talk about like count in …. 5 lectures?
What is this RWX Nonsense?
-
r
= read,w
= write,x
= execute.-rwx------
User permissions ----rwx---
Group permissions -------rwx
Other permissions -
Directory permissions begin with a
d
instead of a-
- Other : “neither the owner, nor a member of the group”.
-
Directory permissions begin with a
An example
-
What would the permissions
-rwxr-----
mean?- It is a file.
- User can read and write to the file, as well as execute it.
- Group members can read the file
- Group members cannot write to or execute the file.
- Other cannot do anything with it.
-
For the formula hungry, you can represent
r
,w
, andx
as binary variables (where 0 is off, and 1 is on). Then the formula for the modes isOctal Ownership Permissions
r ⋅ 2 2 + w ⋅ 2 1 + x ⋅ 2 0
-
Examples
-
chmod 755
:rwxr-xr-x
-
chmod 777
:rwxrwxrwx
-
chmod 600
:rw-----
-
-
If that makes less sense to you, feel free to ignore it.
-
Just use the
stat
command to help you convert :)
-
Just use the
-
The octal version can be confusing, but will save you time. Excellent resource in [Computer Hope 2016 ] .
Flags and Options: Formats
-
A flag that is
-
One letter is specified with a single dash (
-a
). -
More than one letter is specified with two dashes (
--all
). - The reason is because of how switches can be combined.
-
One letter is specified with a single dash (
-
We generally use “flag” and “switch” interchangeably:
- “flag” the command, telling it that “action X” should occur
- specify to the command to “switch on/off action X”
Flags and Options: Switches
- Switches take no arguments, and can be specified in a couple of different ways.
- Switches are usually one letter, and multiple letter switches usually have a one letter alias.
-
One option:
-
ls -a
-
ls --all
-
-
Two options:
-
ls -l -Q
-
ls -lQ
-
-
Usually
applied from left to right in terms of operator precedence, but not always:
- This is up to the developer of the tool.
-
Prompts:
rm -fi <file>
-
Does
not
prompt:
rm -if <file>
Flags and Options: Argument Specifiers
-
The
--argument="value"
format, where the=
and quotes are needed ifvalue
is more than one word.-
Yes:
ls --hide="Desktop" ~/
-
Yes:
ls --hide=Desktop ~/
- One word, no quotes necessary
-
No:
ls --hide = "Desktop" ~/
-
Spaces by the
=
will be misinterpreted -
It used
=
as the argument tohide
-
Spaces by the
-
Yes:
-
The
--argument value
format (space after theargument
).- Quote rules same as above.
-
ls --hide "Desktop" ~/
-
ls --hide Desktop ~/
-
Usually,
--argument value
and--argument=value
are interchangeable.- Not always!
Caution About Shebang
- The shebang must be the first line.
-
Generally speaking, best approach is to use
env
:#!/usr/bin/env bash #!/usr/bin/env python
-
Generally, it is “wrong” to hard-code say
#!/bin/bash
-
If I have a custom installation of
bash
that I want to use, your script will ignore me and use the default systembash
.
-
If I have a custom installation of
-
There times
ARE
you do this, but they are very uncommon.
- Example: program that interfaces with the operating system.
-
Then you
do
want to hard-code paths to
/bin
or/usr/bin
.
-
Not a
#
commentable language?- Official answer: just don’t use a shebang.
- Unofficial answer: technically it doesn’t matter, since the shebang is a hack on the first 8 bits, but this would render the file useless except for when it is executed by a shell.
Shebang Case Study: System Tool Counterexample
-
Consider the tool
gnome-tweak-tool
. It’s purpose is to alter system configurations of the desktop manager Gnome. -
Their shebang:
#!/usr/bin/env python
-
This is “wrong”. My operating system uses
/usr/bin/python
behind the scenes for displaying windows etc. -
I have a
custom
python installation that I use for daily hacking.
-
gnome-tweak-tool
uses my custom python, instead of using the system python. -
Should be using
/usr/bin/python
.
-
-
Why is it “wrong”? The
gi.repository
library imported refers to my custom python, not the system python. -
This “bug” has been around for years with no change. There has to be a reason?
Shebang Details
-
The Shebang does not need a space, but can have it if you want. The following all work:
#!/usr/bin/env bash #! /usr/bin/env bash #! /usr/bin/env bash #! /usr/bin/env bash
-
The
#!
is the magic (yes, that is the technical term):-
The
#!
must be the very first two characters, and - the executable separated by whitespace on the same line .
-
The
-
Recall that starts
#
is a comment inbash
.- Technically this line is never “executed” by the script .
-
The
shell
launching the script to determine how to launch.
-
In general, you will see either one space or no spaces.
- Best to stick with one of those for consistency ;)
Shebang Limitations
-
Generally, only safe to use two arguments in shebang:
- The interpretor.
- An optional set of arguments.
-
So when you do
/usr/bin/env
, technically-
/usr/bin/env
is the “interpretor” -
bash
is the argument.
-
-
This means that if you want to use
perl
orawk
or something, you are limited to single letter flags. E.g. if you want-a
,-b
,-c
, you would have to do/usr/bin/perl -abc
.-
/usr/bin/env
cannot be used! - [Interesting mail thread][04_env_mail].
-
-
[Amusing hacks available][04_shebang_hacks].
find [where to look] criteria [what to do]
- Used to locate files or directories.
- Search any set of directories for files that match a criteria.
-
Search by name, owner, group, type, permissions, last modification date, and
more
.
-
Search is recursive (will search all subdirectories too).
- Sometimes you may need to limit the depth.
-
Search is recursive (will search all subdirectories too).
- Comprehensive & flexible. Too many options for one slide.
nano file
vim file
emacs file
git [--version] [--help] [-C <path>] [-c <name>=<value>]
[--exec-path[=<path>]] [--html-path] [--man-path]
[--info-path] [-p|--paginate|--no-pager]
[--no-replace-objects] [--bare] [--git-dir=<path>]
[--work-tree=<path>] [--namespace=<name>]
<command> [<args>]
-
Do
not
expect to learn
git
once and be done. - You will learn it steadily, over time. The sooner you start, the better off you will be in your deveolpment career.
-
Git is not just for CS Majors
.
- It is for anybody working with any code.
Some Useful Find Options
-
-name
: name of file or directory to look for. -
-maxdepth num
: search at mostnum
levels of directories. -
-mindepth num
: search at leastnum
levels of directories. -
-amin n
: file last access wasn
minutes ago. -
-atime n
: file last access wasn
days ago. -
-group name
: file belongs to groupname
. -
-path pattern
: file name matches shell patternpattern
. -
-perm mode
: file permission bits are set tomode
.
Of course…a lot more in
man find
.
Some Details
- This command is extremely powerful…but can be a little verbose (both the output, and what you type to execute it). That’s normal.
-
Modifiers for
find
are evaluated in conjunction (a.k.a AND). -
Can condition your arguments with an OR using the
-o
flag.- Must be done for each modifier you want to be an OR.
-
Can execute command on found files / directories by using the
-exec
modifier, andfind
will execute the command for you.-
The variable name is
{}
. -
You have to end the command with either a
-
Semicolon (
;
): execute command on each result as you find them. -
Plus (
+
): find all results first, then execute command. -
Warning: have to escape them, e.g.
\;
and\+
-
The
;
and+
are shell expansion characters!
-
Semicolon (
-
The variable name is
Basic Examples
Find all files accessed at most 10 minutes ago
find . -amin -10
Find all files accessed at least 10 minutes ago
find . -amin +10
Comparing AND vs OR behavior
find . -type f -readable -executable
- All files that are readable and executable .
find . -type f -readable -o -executable
- All files that are readable or executable .
Display all the contents of files accessed in the last 10 minutes
find . -amin -10 -exec cat {} \+
On a Mac and ended up with .DS_Store Everywhere?
find . -name ".DS_Store" -exec rm -f {} \;
-
Could be
;
or+
sincerm
allows multiple arguments.
Solve maze in one line
Maze in 2 seconds
find / -iname victory -exec handin maze {} \+
-
imagine how much more complicated
maze
could get in the real world…
More Involved Example
- Your boss asks you to backup all the logs and send them along.
- Combining some of the things we have learned so far (also zip)
# Become `root` since `/var/log` is protected:
$ sudo su
<enter password for your user>
# Make a containment directory to copy things to
$ mkdir ~/log_bku
# `find` and copy the files over in one go
$ find /var/log -name "*.log" -exec cp {} ~/log_bku/ \;
# The `cp` executed as `root`, so we cannot read them.
$ chown -R mpm288 ~/log_bku # My netID is mpm288
# Give the folder to yourself.
$ mv ~/log_bku /home/mpm288/
# Become your user again
$ exit
# Zip it up and send to your boss
$ zip -r log_bku.zip ~/log_bku
More Involved Example: Analysis
-
Don’t
have
to be
root
:sudo find
was too long for slides.-
Make the directory
<dir>
as normal user. -
sudo find ... -exec cp {} <dir> \;
-
sudo chown -R <you> <dir>
-
zip -r <dir>.zip <dir>
-
Make the directory
-
Cannot
use
\+
instead of\;
in this scenario:-
Suppose you found
/var/log/a.log
and/var/log/b.log
. -
Executing with
\;
(-exec
as youfind
):-
cp /var/log/a.log ~/log_bku/
-
cp /var/log/b.log ~/log_bku/
-
-
Executing with
\+
(find
all first, then-exec
once):-
cp /var/log/a.log /var/log/b.log ~/log_bku/
-
cp
gets mad: you gave three arguments
-
-
Suppose you found
-
The high-level story is: nothing special.
- Just a sequence of operations being performed.
- Runs from top to bottom.
-
Common practice:
- Executable filetype.
- Shebang.
Bash Scripting at a Glance
|
|
#!/bin/bash
#this is a comment. Maze solution script!
find / -iname victory -exec handin maze {} \+
Some execution details
-
Run your scripts by providing a
qualified path
to them.
- path must start with a folder
-
Current directory? use
./scriptname
- somewhere else? specify the path to your script
- Scripts execute from top to bottom.
- This is just like Python, for those of you who know it already.
- Bad code? you may only realize it when (and if) the script reaches that line
- The script starts at the top of the file.
-
Execution continues down until the bottom (or
exit
called).- Broken statement? It still keeps executing the subsequent lines.
The 3 Main Modes of VIM
-
Normal Mode:
- Launching pad to issue commands or go into other modes.
- Can view the text, but not edit it directly (only through commands).
-
Return to normal mode
from other modes
: press
ESCAPE
-
Visual Mode:
- Used to highlight text and perform block operations.
-
Enter visual mode
from normal mode
: press
v
-
Visual Line:
shift+v
-
Visual Block:
ctrl+v
- Explanation: try them out, move your cursor around…you’ll see it.
-
Visual Line:
-
Insert Mode:
- Used to type text into the buffer (file).
- Like any regular text-editor you’ve seen before.
-
Enter
from normal mode
: press
i
Moving Around VIM
- Most of the time, you can scroll with your mouse / trackpad.
- You can also use your arrow keys.
-
VIM shortcuts exist to avoid moving your hands at all. Use
-
h
to go left. -
j
to go down. -
k
to go up. -
l
to go right.
-
-
Hardcore VIM folk usually map left caps-lock to be
ESCAPE
.- Goal: avoid moving your wrists at all costs. Arrows are so far!
- I don’t do this. I also don’t use VIM.
Useful Commands
:help
|
help menu, e.g. specify
:help v
|
:u
|
undo |
:q
|
exit |
:q!
|
exit without saving |
:e [filename]
|
open a different file |
:syntax [on/off]
|
enable / disable syntax highlighting |
:set number
|
turn line numbering on |
:set nonumber
|
turn numbering off (e.g. to copy paste) |
:set spell
|
turn spell checking on |
:set nospell
|
turn spell checking off |
:sp
|
split screen horizontally |
:vsp
|
split screen vertically |
<ctrl+w> <w>
|
rotate between split regions |
:w
|
save file |
:wq
|
save file and exit |
<shift>+<z><z>
|
alias for
:wq
(hold shift and hit
z
twice)
|
WOW How about no. let’s see Emacs
- Basic editing works like notepad (except no mouse)
- No switching between modes to edit/search/save/etc.
- Emacs can also be installed on pretty much every OS.
-
Allows you to edit things
moderately
quickly…
- …and keeps getting faster as you learn it
Emacs modes
[cmd=(
emacs
) An editor, also from 1976.]
emacs file
[/cmd]
-
Based on file and action type
- Java file detected? IDE mode engaged!
- Plain file detected? Basic edit mode engaged!
- LaTeX file detected? TeXstudio mode!
-
Shortcuts and actions
mostly
independent of mode
- But modes hide a lot of power…
- Sometimes accused of being a whole OS.
Moving around and basic editing:
- move by character? Use the arrow keys!
- move by word? Hold control and use the left/right arrow keys!
- move by paragraph? Hold control and use the up/down arrow keys!
- Saving: hold CTRL, press X then S (all while holding control
- Closing: hold CTRL, press X then C (all while holding control)
-
Convention: C-x means “hold control, press x”
- C-x C-s means “press x and s, all while holding control”
- These editors predate “normal” shortcuts!
Useful Shortcuts
C-x C-f | Open a file for editing |
C-x C-s | Save the current file |
C-x C-c | exit |
C-x b | change to a different open file |
C-space (arrow key) | Start highlighting (marking) a region |
C-w | Cut the code in the highlighted region |
Alt-w | Copy the code in the highlighted region |
C-g | Quit (cancel command, “escape”) |
C-y | paste |
C-s | search (find) |
Escape-x | Enter a command by name (C-g to quit) |
C-x k | close a file (it will ask) (emas stays open) |
Escape-$ | spellcheck the word under the cursor |
Escape-x ispell | spellcheck the highlighted region |
Escape-x help | Get just a lot of help information |
Escape-x
<tab>
|
List ALL THINGS EMACS CAN DO |
-
git
is a decentralized version control system. - Like “historic versions” for DropBox/OneDrive
- Except far more advanced, and more streamlined
-
It enables you to save changes as you go to your code.
- As you make these changes, if at any point in time you discover your code is “broken”, you can revert back in time!
- Of course, if you haven’t been “saving” frequently, you have less to work with.
- Mantra: commit early and often.
-
Can also
share
your code with friends!!
- Can work on same version, or…
- can “go back in time” to latest working one!
- You will have trouble – we all do.
- The tracked folder is called a repository ( repo )
-
You
git init .
to create repository “here” -
To
track
a file in a repository, you
git add <filename>
-
The act of “saving” is
commit
, and needs a message
-
to commit all tracked files,
git commit -a -m 'your message here'
-
to commit all tracked files,
-
To copy a repository, you
git clone
it -
To work with friends, you need to
-
git clone
their (or a common) repository -
git pull /other/repo/path
their changes
-
-
if you edited the same file, you get a
conflict
- if you have uncommitted changes, you can’t pull
zip <name_of_archive> <files_to_include>
-
E.g.
zip files.zip a.txt b.txt c.txt
-
Extracts to
a.txt
,b.txt
, andc.txt
in current directory . -
To do folders, you need recursion.
-
zip -r folder.zip my_files/
-
Extracts to folder named
my_files
in current directory . -
Good practice to ALWAYS zip a folder and distribute with the name it will extract as.
-
zip -r folder_name.zip folder_name/
-
-
Drives me crazy when I get a
.zip
that extracts files in the same directory… very difficult to keep track of.
-
unzip <archive_name>
-
Use
-l
to list what would extract before doing it.
gzip <files_to_compress>
-
Less time to compress, larger file:
--fast
-
More time to compress, smaller file:
--best
-
Read the
man
page, lots of options. -
By default,
replaces
the original files!
-
You can use
--keep
to bypass this.
-
You can use
gunzip <archive_name>
-
Use
-l
to list what would extract before doing it.
tar -cf <tar_archive_name> <files_to_compress>
-
C
reate a tar archive.
tar -xf <tar_archive_name>
-
E
x
tract all files from archive.
-
tar
is a stream tool. By default, it is expecting stream input. -
Don’t forget the
-f
if you are working with files!
- This is a non-exhaustive list. There are many out there.
-
Similar interface to
gzip
: -
Honorable mentions:
-
file.rar
: a “RAR” archive; used for distributing large files-
file.rar.001
,file.rar.002
, etc: multiple archives needed to reconstruct whole. - You extract the first one, it looks for the others in same directory.
-
-
file.7z
: “7”-zip , successor to RAR, uses LZMA-
If you are choosing between
.rar
and.7z
…choose.7z
.
-
If you are choosing between
-
Install
unrar
to deal with these on Unix.
-
-
Moral
:
-
Working with
tar
and/or only Unix? Usexz
. -
Have to support Windows fools?
Use
7zip
.
-
Working with
tar -c[zjJ]f <archive_name> <source_files>
tar -x[zjJ]f <archive_name>
-
[zjJ]
here means eitherz
,j
, orJ
— only one . - YOU have to specify the file extension.
-
Use
gzip
compression method:-z
(or--gzip
)-
Extension convention:
.tar.gz
-
Example:
tar -czf files.tar.gz files/
-
Extension convention:
-
Use
bzip2
compression method:-j
(or--bzip2
)-
Extension convention:
.tar.bz2
-
Example:
tar -cjf files.tar.bz2 files/
-
Extension convention:
-
Use
xz
compression method:-J
(or--xz
)-
Extension convention:
.tar.xz
-
Example:
tar -cJf files.tar.xz files/
-
Extension convention:
wc [options] <file>
-
count the number of lines:
-l
-
count the number of words:
-w
-
count the number of characters:
-m
-
count the number of bytes:
-c
sort [options] <file>
-
Default: sort by the
ASCII
code ( roughly alphabetical, see [ASCII Table 2010 ] ) for the whole line. -
Use
-r
to reverse the order. -
Use
-n
to sort by numerical order. -
Use
-u
to remove duplicates.
uniq [options] <file>
-
No flags: discards all but one of successive identical lines.
- Unique occurrences are merged into the first occurence.
-
Use
-c
to prints the number of successive identical lines next to each line. -
Use
-d
to only print repeated lines.
tr [options] <set1> [set2]
-
Translate or delete characters / sets.
- We will cover POSIX / custom sets soon.
-
By default, searches for strings matching
set1
and replaces them withset2
. -
If using
-d
to delete, onlyset1
is specified. -
Can use
-c
to invert (complement) the set.
- The tracked folder is called a repository ( repo )
-
You
git init .
to create repository “here” -
To
track
a file in a repository, you
git add <filename>
-
The act of “saving” is
commit
, and needs a message
-
to commit all tracked files,
git commit -a -m 'your message here'
-
to commit all tracked files,
-
use
git log
to view all your commits (q quits) -
use
git checkout <hash>
to temporarily revert your files to an old commit
Demo Time! Everybody!
cd ~/course/cs2043/demos/git-demo
nano demo-file
git commit -a -m ‘mucking with the demo’
git log
git checkout 1ff647
The arrow of time, and branching
- So that last command produced quite the message, eh?
-
Where should a commit “go” now?
- after the last commit?
- But you’re in the past now…
-
Can create a new “branch” of time
- An “alternate history”
- What if I did this instead of that?
-
Create a branch with
git checkout -b <new-branch-name>
- lots of other ways
-
Can
checkout
a branch to re-enter that timeline
back to the demo
git checkout -b alternate-timeline
git checkout master
Time travel is only fun when you merge!
git merge alternate-timeline
-
Git tries to apply everything that happened in
alternate-timeline
to your current branch - could very easily break! This is a conflict
Working with Friends
-
To copy a repository, you
git clone
it -
To work with friends, you need to
-
git clone
their (or a common) repository -
git pull /other/repo/path
their changes - Always commit (or “stash”) before you pull
-
-
Bash scripting is all about combining simple commands together to do more powerful things. This is accomplished using the “pipe” character.
Piping
<command1> | <command2>
-
Pass output from
command1
as input tocommand2
. -
Works for almost every command.
-
Note:
echo
does not allow you to pipe to it! Usecat
instead :)
-
Note:
- In some senses, the majority of commands you will learn in this course were designed to support this.
-
Pass output from
Some Piping Examples
-
1, 2, 3…easy as ABC?
Piping along…
$ ls -al /bin | less
-
Scroll through the long list of programs in
/bin
$ history | tail -20 | head -10
- The 10 th - 19 th most recent commands executed.
$ echo * | tr ' ' '\n'
- Replaces all spaces characters with new lines.
-
Execute just
echo *
to see the difference.
-
Scroll through the long list of programs in
-
In all of these examples, try executing it first without the
|
-
First: execute
history
-
Next: execute
history | tail -20
-
Last: execute
history | tail -20 | head -10
-
First: execute
-
The redirection operators are:
>
,>>
,<
, or<<
.-
To redirect standard output, use the
>
operator.-
command > file
-
-
To redirect standard input, use the
<
operator.-
command < file
-
-
To redirect standard error, use the
>
operator and specify the stream number2
.-
command 2> file
-
-
Combine streams together by using
2>&1
syntax.- This says: send standard error to where standard output is going.
- Useful for debugging / catching error messages…
-
…or ignoring them (you will often see that sent to
/dev/null
).
-
To redirect standard output, use the
Redirection Example
-
Bash processes I/O redirection from left to right, allowing us to do fun things like this:
Magic
tr -dc '0-9' < test1.txt > test2.txt
-
Deletes everything but the numbers from
test1.txt
, then store them intest2.txt
. -
CAUTION: do not
ever
use the same file as output that was input.
-
Example:
tr -dc '0-9' < original.txt > original.txt
- You will lose all your data, you cannot read and write this way.
-
Example:
-
Deletes everything but the numbers from
-
Piping and Redirection are quite sophisticated, please refer to the Wikipedia page in [Wikipedia 2017 ] .
Exit Codes
-
When you execute commands, they have an “exit code”.
- This how you “signal” to others in the shell: through exit codes.
-
The exit code of the
last command executed
is stored in
$?
-
There are various exit codes, here are a few examples:
$ super_awesome_command bash: super_awesome_command: command not found... $ echo $? 127 $ echo "What is the exit code we want?" What is the exit code we want? $ echo $? 0
-
The success code we want is actually
0
. Refer to [The Linux Documentation Project 2017 a ] . -
Remember
cat
with no args? You will have toctrl+c
to kill it, what would the exit code be?
Executing Multiple Commands in a Row
- With exit codes, we can define some simple rules to chain commands together:
-
Always execute:
$ cmd1; cmd2 # exec cmd1 first, then cmd2
-
Execute conditioned upon exit code of
cmd1
:$ cmd1 && cmd2 # exec cmd2 only if cmd1 returned 0 $ cmd1 || cmd2 # exec cmd2 only if cmd1 returned NOT 0
-
Kind of backwards, in terms of what means continue for
and
, but that was likely easier to implement since there is only one
0
and many not0
’s.
-
Kind of backwards, in terms of what means continue for
and
, but that was likely easier to implement since there is only one
|
|
-
Double brackets (
bash
only!)[[ expr ]]
allow for more features e.g., boolean operations. -
both
[
and[[
are actually commands!if [[ CONDITION_1 ]] || [[ CONDITION_2 ]]; then # statements fi
-
elif
andelse
clauses allowed , not required .
-
BE VERY CAREFUL WITH SPACES!
- Spaces on both the outside and the inside necessary !
# bash: syntax error near unexpected token `then`
if[[ 0 -eq 0 ]]; then echo "Hiya"; fi
# bash: [[0 command not found...
if [[0 -eq 0 ]]; then echo "Hiya"; fi
# bash: syntax error in conditional expression:
# unexpected token `;'
# bash: syntax error near `;'
if [[ 0 -eq 0]]; then echo "Hiya"; fi
# This has spaces after if, and before brackets (works)!
if [[ 0 -eq 0 ]]; then echo "Hiya"; fi
Test Expressions
-
[
and[[
have a special set of commands that allow checks. -
Numerical comparisons (often used with variables):
-
$n1 -eq $n2
tests if n 1 = n 2 . -
$n1 -ne $n2
tests if n 1 ≠ n 2 . -
$n1 -lt $n2
tests if n 1 < n 2 . -
$n1 -le $n2
tests if n 1 ≤ n 2 . -
$n1 -gt $n2
tests if n 1 > n 2 . -
$n1 -ge $n2
tests if n 1 ≥ n 2 . -
If either
$n1
or$n2
are not a number, the test fails .
-
-
String comparisons:
-
"$s1" == "$s2"
tests ifs1
ands2
are identical. -
"$s1" != "$s2"
tests ifs1
ands2
are different. -
Make sure you have spaces!
-
"$s1"=="$s2"
will fail …
-
-
For strings in particular,
use double quotes
!
- If string has spaces and no double quotes used, it will fail .
-
Path Testing
-
Test if
/some/path
exists:-e /some/path
-
Test if
/some/path
is a file:-f /some/path
-
Test if
/some/path
is a directory:-d /some/path
-
Test if
/some/path
can be read:-r /some/path
-
Test if
/some/path
can be written to:-w /some/path
-
Test if
/some/path
can be executed:-x /some/path
-
Test if
/some/path
is an empty file:-s /some/path
Path Testing Example
#!/usr/bin/env bash
path="/tmp"
if [[ -e "$path" ]]; then
echo "Path '$path' exists."
if [[ -f "$path" ]]; then
echo "--> Path '$path' is a file."
elif [[ -d "$path" ]]; then
echo "--> Path '$path' is a directory."
fi
else
echo "Path '$path' does not exist."
fi
-
Output from script:
Path '/tmp' exists. --> Path '/tmp' is a directory.
|
|
|
|
|
|
-
When you pass arguments to a bash script, you can access them in a few different ways:
-
$1
,$2
, …,$10
,$11
: values of the first, second, etc arguments-
If 3 arguments given,
$4
,$5
, … higher are empty .
-
If 3 arguments given,
-
$0
is the name of the script. -
$#
is the number of arguments (argc
inC
). -
$?
is the exit code of the last program executed.-
You can have your script set this with
exit <number>
(readman exit
). -
No explicit call to
exit
same asexit 0
(aka success).
-
You can have your script set this with
-
$$
is the current process identification number (PID). -
$*
expands$1 .. $n
into one string.-
$*
⟹"$1 $2 ... $n"
(one string)
-
-
$@
expands$1 .. $n
into individual strings.-
$@
⟹"$1"
"$2"
...
"$n"
( n strings)
-
-
|
|
|
|
|
|
-
bash
is one of the few languages that has anuntil
loop:
|
|
-
The
until
loop is exactly how it sounds: execute the loop body until the condition evaluates to true . -
So once
x
is4
,(( x == 4 ))
istrue
, loop stops.-
Loop body not executed when
x == 4
, sox: 4
not printed. -
Like
for
andwhile
, can also use test expressions :until [[ $x -eq 4 ]]; do
-
Loop body not executed when
lsof [options]
-
Very similar to
ps
, with more information by default. - Frequently used for monitoring port connections.
-
Use
-i
to list IP sockets.-
E.g.,
lsof -i tcp:843
shows all tcp processes on port843
.
-
E.g.,
- Many options…read the man page if you are intrigued.
Interactive Shells
- Your environment is already setup and ready to go now that you have logged in.
-
Now do the lightweight configurations, put in your
rc
file.-
The
~/.bashrc
forbash
-
The
~/.kshrc
forksh
-
The
~/.zshrc
forzsh
-
The
-
Things you put in these files:
-
Shell specific
alias
es,function
s, etc.
-
Shell specific
-
Things you
never
do:
-
source ~/.bash_profile
from~/.bashrc
for example. -
It goes the other way:
~/.bash_profile
sources~/.bashrc
-
Initial
login
shell is is when
*profile
get sourced.-
The
~/.bashrc
is not sourced on login automatically. - Only if you do it (almost every distribution does this by default).
-
The
-
ps [options]
- Reports a snapshot of the current running processes, including PIDs.
- By default, only the processes started by the user.
-
Use
-e
to list every process currently running on the system. -
Use
-ely
to get more information than you can handle. -
Use
-u <username>
to list all processes for userusername
. -
Use
-C <processname>
to list all processes matching a name -
Use
ps aux
for “BSD” style ps, works on macOS/*nix
top [flags]
- Displays the amount of resources in percentages each process is using.
-
Use
-d <seconds>
to control the update frequency.- The act of monitoring resources usage uses resources!
-
Use
-u <user>
to show only the processes owned byuser
. -
Use
-p <PID>
to show only the statistics on process with id numberPID
.
htop [flags]
- Displays the amount of resources in percentages each process is using.
-
Use
-d <seconds>
to control the update frequency.- The act of monitoring resources usage uses resources!
-
Use
-u <user>
to show only the processes owned byuser
. -
Use
-p <PID>
to show only the statistics on process with id numberPID
.
nice [options] command
-
Runs
command
with specified “niceness” value (default:10
). -
Niceness
values range from
-20
(highest priority) to19
(lowest priority). -
Only
root
can give a process a negative niceness value. -
Commands run without
nice
have priority0
. -
Example:
nice -n 10 deluge
- Prevent torrents from hogging the CPU.
- … don’t pirate stuff folks
renice <priority> -p <PID>
-
Change
niceness
of process with id
PID
to<priority>
. -
Remember: only
root
can assign negative values. -
You can only
renice
a process you started.-
Of course,
root
canrenice
anything .
-
Of course,
-
renice 5 -p 10275
-
Set the
niceness
of the process with
PID
10275
to5
. -
Slightly lower than normal
niceness
(default:
0
).
-
Set the
niceness
of the process with
-
renice 19 -u username
-
Set
niceness
of
all
processes owned by
username
to19
.
-
Set
niceness
of
all
processes owned by
kill [-signal] <PID>
-
Sends the specified
signal
to the process with idPID
. -
By default (no
signal
given), it terminates execution.-
kill <PID>
same askill -15 <PID>
-
Signal
15
isSIGTERM
(signal terminate).
-
killall [-signal] <name>
-
Kills processes by
name
. -
By default (no
signal
given), it terminates execution.-
killall firefox
same askill -15 firefox
-
Signal
15
isSIGTERM
(signal terminate).
-
ping <server>
-
Measure network response time (latency) to
<server>
and back. -
Sends short bursts to
<server>
, measures time until return. -
Example:
ping google.com
-
Use
ctrl+c
to kill the process (ping
runs until killed).
-
Use
<command> [arguments] &
-
Runs the specified
command
as a background job. - Unless told otherwise, will send output to the terminal!
-
Example:
mplayer best_song_ever.flac &
tee <filename>
-
Redirects output to
<filename>
and still prints it - good for logging within a pipestream!
jobs
- Prints the running, paused, or recently stopped jobs.
-
Prints jobs with their
JOB ID
s.
bg <JOB ID>
-
Resumes the job with id
JOB ID
in the background . -
Without
JOB ID
, resumes last job placed in background.
fg <JOB ID>
-
Resumes the job with id
JOB ID
in the foreground . -
Without
JOB ID
, resumes last job placed in the background.
nohup <command> [args]
-
Background
jobs (started with
&
) end when terminal closed. -
nohup
launchescommand
so it will ignoreSIGHUP
signals. -
nohup mplayer best_song_ever.flac >/dev/null 2>&1 &
disown [flags] jobspec
-
The
-h
flag preventsjobspec
fromSIGHUP
killing it.-
Use if you forgot to launch with
nohup
, for example.
-
Use if you forgot to launch with
-
jobspec
is the job number (e.g., executejobs
to find it). -
E.g., if
mplayer
hasjobID
1
, thendisown -h %1
source <filename> [arguments]
-
Executing
script
B
from scriptA
runsB
in a subshell . -
Sourcing
script
B
from scriptA
executes in current shell .-
If script
B
exit
s, then scriptA
exit
s!
-
If script
-
Think of it like copy-pasting
B
intoA
at the line wheresource B
is written inA
. -
Just like
#include <header.h>
inC
if you know it. -
Fundamental to the initial shell setup process:
-
All dotfiles related to your
shell
are sourced .
-
All dotfiles related to your
chsh -s /absolute/path/to/new/shell username
-
GNU and BSD
chsh
are slightly different, read theman
page ! -
Example usage to change
$SHELL
forusername
:$ sudo chsh -s /bin/zsh username
-
Warning
: do
not
change the
$SHELL
of theroot
user! -
Typically,
chsh
will modify/etc/passwd
-
grep
yourusername
and read last field.
-
- Kill signals can be used by number or name.
-
TERM
or15
: terminates execution (default signal sent withkill
andkillall
). -
HUP
or1
: hang-up (restarts the program). -
KILL
or9
: like bleach, can kill anything. -
Some examples:
# Terminates process with PID 9009. $ kill 9009 # REALLY kills the process with PID 3223. $ kill -9 3223 # Restarts the process with PID 12221. # Particularly useful for servers / daemon processes. $ kill -HUP 12221
-
Remember
top
andhtop
? They can both renice and kill
-
“Dotfiles” change, add, or enhance existing functionality.
-
The files reside in your home (
~
) directory. -
They are hidden files: their names start with a
.
-
The files reside in your home (
- Some common dotfiles you’ll hear about:
~/.bashrc
|
Controls
bash
terminal behavior
*
|
~/.bash_profile
|
Controls
bash
environment variables
*
|
~/.profile
|
Controls
shell
environment variables
*
|
~/.vimrc
|
Controls the behavior of
vim
|
~/.emacs
|
Controls the behavior of
emacs
|
~/.gitconfig
|
Controls the behavior of
git
|
~/.tmux.conf
|
Controls the behavior of
tmux
(covered later)
|
- There are many possible dotfiles to customize.
-
We will focus on configuring our shell (
bash
).
* What these do depends on what you write in them! See lecture demo .
A Reminder: common environment variables
-
$PATH
: where your shell looks to find programs -
$EDITOR
: your preferred editor (defaults to nano) -
$LANG
: your language and file encoding -
$LD_LIBRARY_PATH
: where your dynamic libraries are (not always set) -
$USER
: who you are -
$HOME
: your home directory -
$TERM
: how fancy your terminal can be -
$MANPATH
: places to find man pages
Login Actions: Precursor
-
There is even still an important distinction:
- A graphical login (logging in through the GUI).
-
A login shell (disabled GUI, or used
ssh
or something).
-
Graphical logins:
- I will not cover this. There is way too much going on.
- Depends on what your GUI (Gnome, KDE, etc) is.
-
A
fantastic
explanation in
[Wooledge
2015
]
.
- Hey! Look around the rest of the site!
- Lots of other great information available!!!
-
Login shells:
- For simplicity, assume that when you login through your GUI, it triggers a login shell to be called.
- This is mostly true, but not exactly.
-
Discussion to come: Bourne shells (
bash
,ksh
, …) vszsh
-
Only because Bourne shells and
zsh
are “incompatible”.
-
Only because Bourne shells and
Login Shells
-
Where do the environment variables like
$PATH
come from? -
For Bourne Shells:
-
System level configuration files are sourced. Same for all users.
-
The file
/etc/profile
is sourced. -
Do
NOT
edit this file directly. It sources
anything
found in
/etc/profile.d/*.sh
. Put additional resources there. -
This is where
PATH
among many other variables is getting set!
-
The file
-
User-level configuration files are sourced (if found).
-
bash
looks for~/.bash_profile
first . If it sees it, it sources it. -
Only if
bash
does not find~/.bash_profile
, it looks for~/.bash_login
next and then~/.profile
last. -
ksh
, on the other hand, only looks for~/.profile
.
-
-
System level configuration files are sourced. Same for all users.
-
For
zsh
, the same pattern occurs:-
System level configuration:
/etc/zprofile
.-
Typically, it
emulates
ksh
and sources/etc/profile
!
-
Typically, it
emulates
-
Look for
~/.zprofile
.
-
System level configuration:
Know Your Shell
-
$SHELL
reports your default shell (echo $SHELL
). -
How do I know what my shell looks for and in what order?
-
man <shell>
and search forINVOCATION
as well asFILES
. -
Or cruise the Arch Wiki – they’re great! E.g.
Arch on
zsh
.
-
alias <new-name> <old-name>
-
Aliases
new-name
to beold-name
, e.g.alias ..='cd ..'
-
Can now type
..
to go up one directory.
-
Can now type
-
Should not ever be used in scripts.
- Disabled by default, battle to use them — very bad practice.
- I don’t have your aliases, so now I can’t run your script.
-
Usually stored in
~/.<shell>rc
file, though~/.<shell>_aliases
is slowly gaining traction.-
Make sure you
source
~/.<shell>_aliases
from~/.<shell>rc
or else they won’t be available!!! -
E.g.
bash
:~/.bashrc
sources~/.bash_aliases
, or -
zsh
:~/.zshrc
sources~/.zsh_aliases
-
Make sure you
scp [flags] <from> <to>
-
It’s exactly like
cp
, only you are transferring over the web. -
Can transfer
from
the
client
to theremote
host. -
Can transfer
from
the
remote
host to theclient
. -
Copy directories just like before using the
-r
flag. -
Must specify the
user
on theremote
host. -
Remote
syntax (for<from>
component):user@host.name:/path/to/file/or/folder
-
You need the
:
to start thepath
.
-
You need the
- If you don’t have permission…you can’t get it!
-
More modern systems may even let you
TAB
complete across theremote
directories :)
git push <url>
tmux [options]
-
tmux
(with no options) starts a new multiplexed instance. - Can split into panes horizontally and vertically.
-
Can
tmux detach
(put in “background”, it’s still running). -
Can
tmux attach
to bring to “foreground” again. -
Can open new windows, sessions, panes, and more.
-
Use
tmux list-*
commands for active info:-
list-buffers
,list-clients
,list-commands
,list-keys
,list-panes
,list-sessions
,list-windows
.
-
-
Use
-
Use
ctrl+D
to close current in-focus pane / window.- If you close the last pane of a session, that session ends.
-
On
ugclinux
(CS Undergraduate servers) I ammpm288
:-
v1:
ssh mpm288@ugclinux.cs.cornell.edu
-
v2:
ssh -l mpm288 ugclinux.cs.cornell.edu
-
v1:
-
Sweet!
ugclinux
has Matlab, can I use it?$ /usr/local/MATLAB/R2012a/bin/matlab Warning: No display specified. You will not be able to display graphics on the screen. >> exit() # exit() left Matlab $ exit # close the ssh connection
-
Now do:
ssh -X mpm288@ugclinux.cs.cornell.edu
$ /usr/local/MATLAB/R2012a/bin/matlab # Matlab displays on my screen now!
-
Transfer from
remote
to local computer:$ scp mpm288@blargh.ru:/home/mpm288/colorize.sh ~/Desktop/ colorize.sh 100% 3299 3.2KB/s 00:00
-
Transfer from
remote
to local computer (using~
is only difference):$ scp mpm288@blargh.ru:~/colorize.sh /usr/share/ colorize.sh 100% 3299 3.2KB/s 00:00
-
Transfer from the
client
to theremote
(just reverse it):$ scp /usr/share/colorize.sh mpm288@blargh.ru:~/Desktop/ colorize.sh 100% 3299 3.2KB/s 00:00
-
As with regular
cp
, can give a new name at same time:$ scp /usr/share/colorize.sh mpm288@blargh.ru:~/new_name.sh colorize.sh 100% 3299 3.2KB/s 00:00
Brief Notes on Multiplexing with
tmux
- Learn the hotkeys: http://tmuxcheatsheet.com/
-
After you
ssh
in, justtmux attach
to open top-level session.-
Not sure which session?
tmux ls
, thentmux attach -t <num>
-
Not sure which session?
-
Where is my mouse?!!!
-
Use
shift+click
to highlight with your mouse. -
May want to bring the current
pane
to full-screen temporarily with
<cmd-seq>+Z
.-
<cmd-seq>
isctrl+B
by default, but can change it. -
Un-fullscreen with another
<cmd-seq>+Z
.
-
-
Use
Further
tmux
Customization
-
Configurations go in a “dotfile”:
~/.tmux.conf
-
Save your layouts with
teamocil
!-
gem install teamocil
- See http://www.teamocil.com/ for more information.
-
-
First run
tmux
, then launchteamocil <name>
grep <pattern> [input]
-
Searches
input
for all lines containingpattern
. -
As easy as searching for a
string
in afile
. - Or it can be much more, using regular expressions.
-
Common use:
<command> | grep <thing you need to find>
-
You have some
command
or sequence of commands producing a large amount of output. -
The output is longer than you want, so filter through
grep
. - Reduces the output to only what you really care about!
-
You have some
-
Understanding how to use
grep
is really going to save you a lot of time in the future!
-
The
*
matches any string , including the null string . - It is a “greedy” operator: it expands as far as it can.
- Is related to the Kleene Star , matching 0 or more occurrences.
-
For shell,
*
is a glob . See [The Linux Documentation Project 2017 c ] for more.# Does not match: AlecBaldwin $ echo Lec* Lec.log Lecture1.tex Lecture1.txt Lecture2.txt Lectures
# Does not match: sure.txt $ echo L*ure* Lecture1.tex Lecture1.txt Lecture2.txt Lectures
-
This is the greedy part:
L*
⇒Lect
# Does not match: tex/ directory $ echo *.tex Lecture1.tex Presentation.tex
-
This is the greedy part:
-
Matces existing files/dirs , does not define sequence
-
The
?
matches a single character.# Does not match: Lec11.txt $ echo Lec?.txt Lec1.txt Lec2.txt Lec3.txt
-
Lec
11
not matched because it would have to
consume
two characters, the
?
is exactly one character- Which character, though, doesn’t matter.
# Does not match: ca cake $ echo ca? can cap cat
-
Lec
11
not matched because it would have to
consume
two characters, the
-
Again matches existing files/dirs!
-
[brackets]
are used to define sets .- Use a dash to indicate a range of characters.
-
Can put commas between characters / ranges (
[a-z,A-Z]
).- Means either one lower case or one upper case letter.
-
[a-z]
only matches one character.-
[a-z][0-9]
: “find exactly one character ina..z
, immediately followed by one character in0..9
”
-
Input | Matched | Not Matched |
---|---|---|
[SL]ec*
|
Lecture Section
|
Vector.tex
|
Day[1-3]
|
Day1 Day2 Day3
|
Day5
|
[a-z][0-9].mp3
|
a9.mp3 z4.mp3
|
az2.mp3 9a.mp3
|
Inverting Sets
-
The
^
character is represents not .-
[abc]
means eithera
,b
, orc
-
So
[^abc]
means any character that is nota
,b
, orc
.
-
Input | Matched | Not Matched |
---|---|---|
[^A-P]ec*
|
Section.pdf
|
Lecture.pdf
|
[^A-Za-z]*
|
9Days.avi
|
vacation.jpg
|
- sets, inverted or not, again match existing files/dirs
Brace Expansion
-
Brace Expansion
:
{...,...}
matches any pattern inside the comma-separated braces. -
Suports ranges such as
11..
22
ort..z
as well! - Brace expansion needs at least two options to choose from.
Input | Output |
---|---|
{Hello,Goodbye}\ World
|
Hello World Goodbye World
|
{Hi,Bye,Cruel}\ World
|
Hi World By World Cruel World
|
{a..t}
|
Expands to the range
a
…
t
|
{1..99}
|
Expands to the range
1
…
99
|
- Note : NO SPACES before / after the commas!
-
Mapped onto following expression where applicable:
- Following expression must be continuous (whitespace escaped)
- See next slide.
- Braces define a sequence , unlike previous!
Brace Expansion in Action
# Extremely convenient for loops:
# prints 1 2 3 ... 99
$ for x in {1..99}; do echo $x; done
# bash 4+: prints 01 02 03 .. 99
$ for x in {01..99}; do echo $x; done
# Expansion changes depending on what is after closing brace:
# Automatic: puts the space between each
$ echo {Hello,Goodbye}
Hello Goodbye
# Still the space, then *one* 'World'
$ echo {Hello,Goodbye} World
Hello Goodbye World
# Continuous expression: escaped the spaces
$ echo {Hello,Goodbye}\ Milky\ Way
Hello Milky Way Goodbye Milky Way
# Yes, we can do it on both sides. \\n: lose a \ in expansion
$ echo -e {Hello,Goodbye}\ Milky\ Way\ {Galaxy,Chocolate\ Bar\\n}
Hello Milky Way Galaxy Hello Milky Way Chocolate Bar
Goodbye Milky Way Galaxy Goodbye Milky Way Chocolate Bar
Symbols | Meaning |
---|---|
*
|
Multiple character wildcard: 0 or more of any character. |
?
|
Single character wildcard: exactly one, don’t care which. |
[]
|
Create a set, e.g.
[abc]
for
either
a
, or
b
, or
c
.
|
^
|
Invert sets:
[^abc]
for anything
except
a
,
b
, or
c
.
|
{}
|
Used to create enumerations:
{hello,world}
or
{1..11}
|
$
|
Read value:
echo $PWD
reads
PWD
variable, then
echo
|
<
|
Redirection: create stream out of file
tr -dc '0-9' < file.txt
|
>
|
Redirection: direct output to a file.
echo "hiya" > hiya.txt
|
&
|
Job control. |
!
|
Contextual. In Shell history, otherwise usually negate. |
#
|
Comment: anything after until end of line not executed. |
-
Special characters inside
double
quotes “prefer” not to expand
- some still need escaping
-
Special characters in single quotes are never expanded.
# prints the letters as expected $ for letter in {a..e}; do echo "$letter"; done # escaping the money sign means give literal $ character $ for letter in {a..e}; do echo "\$letter"; done # $ is literal now, so doesn't read variable $ for letter in {a..e}; do echo '$letter'; done
-
Pay attention to your text editor when writing scripts.
- Like the slides, there is syntax highlighting.
- It usually changes if you alter the meaning of special characters.
-
If you remember anything about shell expansions, remember the difference between single and double quotes.
Some Useful Grep Options
-
-i
: ignores case. -
-A 20 -B 10
: print 10 lines B efore, 20 lines A fter each match. -
-v
: inverts the match. -
-o
: shows only the matched substring. -
-w
: “word-regexp” – exclusive matching, read the man page . -
-n
: displays the line number. -
-H
: print the filename. -
--exclude <glob>
: ignoreglob
e.g.--exclude *.o
-
-r
: recursive, search subdirectories too.-
Note:
your Unix version may differentiate between-r
and-R
, check theman
page. -
grep -r [other flags] <pattern> <directory>
-
That is, you specify the
pattern
first, and where to search after (just like how thefile
in non-recursivegrep
is specified last).
-
That is, you specify the
-
Regular Expressions
-
grep
, like many programs, takes in aregular expression
as itsinput
. Pattern matching with regular expressions is more sophisticated than shell expansions, and also uses different syntax. -
More precisely, a regular expression
defines
a set of strings – if any part of a line of text is
in the set
,
grep
returns amatch
. -
When we use regular expressions, it is (usually) best to enclose them in quotes to stop the shell from expanding it before passing it to
grep
/ other tools.WARNING
When using a tool like
grep
, the shell expansions we have learned can and do still occur! I strongly advise using double quotes to circumvent this. Or if you want the literal character (e.g. the*
), use single quotes to disable all expansions entirely.
Regular Expression Similiarities
-
Some
regex
patterns are similar / the same.Single Characters are Different
Shell Expansion: ?
Regular Expressions: .
-
?
means something different in regex (Differences slide). -
Example:
grep "t.a"
⇒ lines withtea
,taa
, andsteap
Sets are almost the Same
Shell Expansion: [a-z]
Regular Expressions: [a-z]
- Matches one of the indicated characters.
-
Don’t separate multiple characters with commas in the
regex
form (e.g.[a,b,q-v]
becomes[abq-v]
).
-
A Note on Ranges in Sets
- Like shell wildcards, regex is case-sensitive.
-
How would you match any letter, regardless of case?
- If you take a look at the ASCII codes ( [ASCII Table 2010 ] ), you will see that the lower case letters come after the upper case letters.
-
You should be careful about trying to do something like
[a-Z]
. -
Instead, just do
[a-zA-Z]
. -
Or use the POSIX set
[[:alpha:]]
. -
Note:
some programs
may
accept the range
[a-Z]
.- But it may not actually be the range you think. It depends.
Regular Expression Differences
-
Some of the shell expansion tools are completely different.
Modifiers Apply to the Expression Before Them
?
is 0 or 1 occurences:a?
⇒ 0 or 1a
*
is 0 or more occurences:a*
⇒ 0, 1, … na
’s+
is 1 or more occurences:a+
⇒ 1, 2, … na
’s-
Note
:
+
and?
are extended regular expression characters. -
Must escape (
\+
and\?
) or use-E
oregrep
.
# Nothing happens, they weren't escaped $ grep "f?o+" combined/*.* # f\? can be 0, so h{e,3}llo are found $ grep "f\?o\+" combined/*.* combined/foo.tex:1:foo combined/foo.text:1:foo combined/foo.txt:1:foo combined/h3llo.txt:1:h3llo combined/hello.txt:1:hello
-
Note
:
Curly Braces in Pattern Creation
-
Recall that curly braces are an expansion:
$ echo h{e,3}llo hello h3llo $ echo "h{e,3}llo" h{e,3}llo
-
However, you cannot use them with
grep
like this:# Second expansion: treated as file input to grep # You can only supply *ONE* pattern! $ grep h{e,3}llo combined/*.* grep: h3llo: No such file or directory combined/hello.txt:1:hello # Double quotes won't save you: that's the literal # string 'h{e,3}llo' at this point (so no match). $ grep "h{e,3}llo" combined/*.*
-
AKA you cannot
easily
do these expansions when using
grep
. -
{}
.bash are fundamentally different from the other expansions- defines a sequence, does not match existing targets.
Final Thoughts and Additional Resources
-
The regular expressions we use in our shell are the “Perl Regular Expressions.”
- There are other regular expression syntaxes.
-
Most
tools / languages use
perl
RE syntax.
- “Regular” regular expressions
- Extended regular expressions
-
Python
re
(Regular Expression) module- Many excellent examples, and thorough explanations.
-
Topics of interest:
- Greedy vs non-greedy,
- Positive lookahead vs negative lookahead
- Capturing vs non-capturing
- Probably the best step-by-step tutorial there is
cut <options> [file]
-
Must
specify list of
bytes
(
-b
), characters (-c
), or fields (-f
). -
The
file
is optional, usesstdin
if unspecified.
N
|
Only
N
th
byte, character, or field, counted from
1
.
|
N-
|
N th byte, character, or field, to end of line. |
M-N
|
M th to N th (inclusive) byte, character, or field. |
-N
|
First to N th (inclusive) byte, character, or field. |
M,N,..,X
|
Extract individual items (
1,4,6
: first, fourth, and sixth bytes, characters, or fields).
|
-
E.g.,
-b 2
is “ 2 nd byte ”,-f 3-
is “ 3 rd field to end of line”.
-
Use
-d
to specify a delimiter (TAB
by default).-
E.g.,
echo 'a:b:c:d' | cut -d : -f 2
⟹b
-
E.g.,
-
Use
-s
to suppress line ifdelimiter
not found.
sed [options] [script] [file]
- Stream editor for filtering and transforming text.
-
If no
file
provided,stdin
is used. -
We will focus on
sed
’s's/<regex>/<replacement>/'
:-
Replace anything matching
<regex>
with<replacement>
. -
E.g.,
echo 'hello' | sed 's/lo/p!/'
⟹help!
-
Replace anything matching
-
sed
goes line by line searching for the regular expression. -
Only covering
basics
,
sed
is a full programming language. -
Main difference between
sed
andtr
for scripting?-
sed
can match regular expressions, and perform captures !
-
-
Extended regular expressions: use the
-E
flag ( not-r
).-
GNU
sed
supports both-r
and-E
, BSDsed
only-E
.
-
GNU
- See examples for more.
xargs <command> [args for command...]
- pipe input to xargs or redirect file to xargs
- becomes arguments for xargs’ command
-
like
find
’s-exec
, except no{} \;
shift <number>
- used in shell scripts only!
-
drop the first
arguments -
renumber remaining arguments
-
after
shift
;$2
is$1
,$3
is$2
, etc.
-
after
paste [options] [file1] [file2] ... [fileN]
-
Neither
options
norfiles
are required . -
Use
-d
to specify the delimiter (TAB
by default). -
Use
-s
to concatenate serially instead of side-by-side. -
No
options
and onefile
specified: same ascat
.-
Use with
-s
to join all lines of a file.
-
Use with
split [options] [file [prefix]]
-
Use
-l
to specify how many lines in each file-
Default:
1000
-
Default:
-
Use
-b
to specify how many bytes in each file. -
The
prefix
is prepended to each file produced. -
If no
file
provided (or iffile
is-
),stdin
is used. -
Use
-d
to produce numeric suffixes instead of lexographic.- Not available on BSD / macOS.
join [options] file1 file2
- Join two files at a time, no more, no less.
- Default: files are assumed to be delimited by whitespace .
-
Use
-t <char>
to specify alternative single-character delimiter. -
Use
-1 n
to join by the n th field offile1
. -
Use
-2 n
to join by the n th field offile2
.-
Field numbers start at
1
, likecut
andpaste
.
-
Field numbers start at
-
Use
-a f_num
to display unpaired lines of filef_num
.
employees.csv
Alice,female,607-123-4567,11 Sunny Place,Ithaca,NY,14850
Bob,male,607-765-4321,1892 Rim Trail,Ithaca,NY,14850
Andy,n/a,607-706-6007,1 To Rule Them All,Ithaca,NY,14850
Bad employee data without proper delimiter
-
/course/cs2043/demos/10-demos/employees.csv
-
Get names, ignore improper lines:
$ cut -d , -f 1 -s employees.csv
-
Get names and phone numbers, ignore improper lines:
$ cut -d , -f 1,3 -s employees.csv
-
Get address ( 4 th col and after), ignore improper lines:
$ cut -d , -f 4- -s employees.csv
A Basic Example
-
Luke, there is no spoon (demo file
no_spoon.txt
) .$ head -1 no_spoon.txt There is no spoon. There is no spoon. There is no spoon. There is no spoon. $ sed 's/no spoon/a fork/g' no_spoon.txt There is a fork. There is a fork. There is a fork. There is a fork. ... There is a fork. There is a fork. There is a fork. There is a fork.
-
Replaces
no spoon
witha fork
for every line. -
No ending
/g
? Only one substitution per line:$ sed 's/no spoon/a fork/' no_spoon.txt There is a fork. There is no spoon. There is no spoon. There is no spoon. ... There is a fork. There is no spoon. There is no spoon. There is no spoon.
-
Caution
: get in habit of using
single-quotes
for with
sed
.-
Otherwise special shell characters (like
*
) may expand in double-quotes causing you sadness and pain.
-
Otherwise special shell characters (like
Deletion
-
Delete all
lines
that contain
regex
:sed '/regex/d'
david.txt
Hi, my name is david.
Hi, my name is DAVID.
Hi, my name is David.
Hi, my name is dAVID.
-
Delete all lines in demo file
david.txt
matching[Dd]avid
:$ sed '/[Dd]avid/d' david.txt Hi, my name is DAVID. Hi, my name is dAVID.
-
To delete pattern per-line, just do an empty replacement:
$ sed 's/[ ]\?[Dd][Aa][Vv][Ii][Dd].//g' david.txt Hi, my name is Hi, my name is Hi, my name is Hi, my name is
Regular Expressions
-
What does this
REMOVED
from demo filedata.txt
?$ sed 's/[a-zA-Z]\{1,3\}[0-9]*@cornell\.edu/REMOVED/g' data.txt
-
Only removes
netID@cornell.edu
emails, not the others! -
The
\{1,3\}
.{bash} specifies a number of occurrences
-
Only removes
-
“Regular” regex: escape specials (
(parens)
,{braces}
, etc.).$ sed 's/[[:alnum:]]\{1,11\}@/REMOVED@/g' data.txt
-
We have to escape the curly braces:
\{1,11\}
-
We have to escape the curly braces:
-
“Extended” regex (using
-E
flag): escaping rules reversed !$ sed -E 's/[[:alnum:]]\{1,11\}@/REMOVED@/g' data.txt
-
No replacements,
\{1,11\}
now means literal string{1,11}
.
$ sed -E 's/[[:alnum:]]{1,11}@/REMOVED@/g' data.txt
-
Works!
\{1,11\}
⟹{1,11}
-
No replacements,
Capture Groups
-
Like most regular expressions,
(parens)
form capture groups. -
You can use the capture groups in the replacement text.
-
If you have one capture group:
\1
in replacement text. -
Two groups?
\1
and\2
are available in replacement text.
-
If you have one capture group:
-
A contrived example:
$ echo 'hello world' | \ sed 's/\(hello\) \(world\)/\2 say \1 back/' world say hello back
-
And using regular expressions?
$ echo 'I have a spoon.' | \ sed -E 's/([a-z]+)\./super shiny silver \1!/' I have a super shiny silver spoon!
-
Notice that those
(parens)
are not escaped because of-E
!
-
Notice that those
More
sed
-
Can specify lines to check by numbers or with regex:
# checks lines 1 to 20 $ sed '1,20s/john/John/g' file # checks lines beginning with 'The' $ sed '/^The/s/john/John/g' file
-
The
&
corresponds to the pattern found:# replace words with words in double quotes $ sed 's/[a-zA-Z]\+/"&"/g' no_spoon.txt "There" "is" "no" "spoon". .....
-
Many more resources available here .
Additional
sed
Practice
See
sed Practice
demo folder
.
paste
Examples I
names.txt
Alice
Bob
Andy
phones.txt
607-123-4567
607-765-4321
607-706-6007
-
paste
cut_paste/names.txt
andcut_paste/phones.txt
line by line:$ paste -d , names.txt phones.txt > result.csv $ cat result.csv Alice,607-123-4567 Bob,607-765-4321 Andy,607-706-6007
paste
Examples II
names.txt
Alice
Bob
Andy
phones.txt
607-123-4567
607-765-4321
607-706-6007
-
paste
names.txt
andphones.txt
serially (-s
):$ paste -d , -s names.txt phones.txt > result.csv $ cat result.csv Alice,Bob,Andy 607-123-4567,607-765-4321,607-706-6007
split
Examples I
ages.txt
Alice 44
Bob 30
Candy 12
-
split
split_join/ages.txt
into files of one line each:$ split -l 1 ages.txt $ ls ages.txt salaries.txt xaa xab xac $ cat xaa Alice 44 $ cat xab Bob 30 $ cat xac Candy 12
split
Examples II
ages.txt
Alice 44
Bob 30
Candy 12
-
split
split_join/ages.txt
into files of one line each,-
with numeric suffixes (
-d
) (GNU / Linux), and withages_
prefix
$ split -l 1 -d ages.txt ages_ $ ls ages_00 ages_01 ages_02 ages.txt salaries.txt $ cat ages_00 Alice 44 $ cat ages_01 Bob 30 $ cat ages_02 Candy 12
-
with numeric suffixes (
join
Examples I
ages.txt
Alice 44
Bob 30
Candy 12
salaries.txt
Bob 300,000
Candy 120,000
-
join
split_join/ages.txt
andsplit_join/salaries.txt
files intoresults.txt
:$ join ages.txt salaries.txt > results.txt $ cat results.txt Bob 30 300,000 Candy 12 120,000
join
Examples II
ages.txt
Alice 44
Bob 30
Candy 12
salaries.txt
Bob 300,000
Candy 120,000
-
join
split_join/ages.txt
andsplit_join/salaries.txt
files intoresults.txt
:$ join -a1 ages.txt salaries.txt > results.txt $ cat results.txt Alice 44 Bob 30 300,000 Candy 12 120,000
function <name> {
body...
}
line breaks are essential!
- Just like a switch statement in other languages, only better.
-
Does not carry on to all cases if you forget that
break
keyword.case "$var" in "A" ) cmds to execute for case "A" ;; "B" ) cmds to execute for case "B" ;; * ) cmds for DEFAULT (not matched) case ;;
-
Sort of like shorthand for
if
-
elif
-
else
statements… -
…only not quite the same!
Simple If and Case Examples
-
Make a simple program to print between 0 and 2
blargh
s -
Input is
$1
, explicit check not necessary (else
or*)
case)
|
|
Difference Between Case and If Comparisons
-
The matching strategy is different for
case
thanif
. -
By default,
case
statements are comparing patterns . -
By default,
if
statements are comparing values.-
To use
extended regular expresions
in
if
statements, you need to use the=~
operator. -
Use
[[ double bracket expressions ]]
for extended regular expressions inif
-
The
=~
operator not available for allbash < 4.0
. Checkman bash
and search for=~
.-
Recall: after
man bash
, type/expr
and hit<enter>
to search. So type/=~
and hit<enter>
. -
Cycle through results with
n
for next search result.
-
Recall: after
-
To use
extended regular expresions
in
-
See demo file
sets/case.sh
.#!/usr/bin/env bash case "$1" in [[:digit:]] ) echo "$1 blargh echoes..." for (( i = 1; i <= $1; i++ )); do echo " [$i] blargh" done ;; * ) echo "Blarghs only come in [0-9]." exit 1 ;; esac
Using Sets with If Part 1
-
See demo file
sets/if.sh
.#!/usr/bin/env bash if [[ "$1" =~ [[:digit:]] ]]; then echo "$1 blargh echoes..." for (( i = 1; i <= $1; i++ )); do echo " [$i] blargh" done else echo "Blarghs only come in [0-9]." exit 1 fi
-
Works on
[0-9]
. -
Cool! Works on
99
. -
Whoops! Works on
208a
– thefor
loop crashes!
Using Sets with If Part 2
-
Option 1: negate a negation (read: if not “not a number” ):
# +-----------+ +-----------------+ # | Negate if | | Negate (invert) | # | match | | set | # +-----------+ +-----------------+ # | | if [[ ! "$1" =~ [^[:digit:]] ]]; then
-
Option 2: use a complete extended regular expression pattern :
# +----------------------+ # | ^: beginning of line | # +----------------------+ # | if [[ "$1" =~ ^[[:digit:]]+$ ]]; then # +--------------------+ || +-----------------------+ # | +: 1 or more digit |--++--| $ matches end of line | # +--------------------+ +-----------------------+
Using Sets with If Part 3 (We’re Finsihed, Right?!)
- The last example felt pretty bullet-proof, what can go wrong?
-
Using demo file
eregex/if.sh
:$ ./if.sh 08 ./if.sh: line 4: ((: i <= 08: value too great for base (error token is "08")
-
This is because of the leading
0
—bash
treats this as octal :$ ./if.sh 0111 0111 blargh echos... [1] blargh [2] blargh ... [72] blargh [73] blargh
-
For now, we’ll happily ignore this.
-
Arrays in
bash
are extraordinarily flexible in some senses… - …and particularly fickle in other senses.
-
Short version:
arr=( use parentheses and separate items by spaces )
-
Mixed “types”:
my_arr=( "a string" 1 twelve "33" )
-
Question: what are the types of
twelve
and"33"
-
twelve
would be interpreted as astring
. -
"33"
can be either astring
or a number! -
bash
doesn’t really have a “type system”.my_arr=( "a string" 1 twelve "33" ) echo "Index '3' with '44' added: $(( ${my_arr[3]} + 44 ))" # Prints: # Index '3' with '44' added: 77
-
Citation Matters!
-
The majority of the remaining examples are either copied or modified from
[Bash Reference Manual
2017
b
]
.
- A truly excellent resource, worth reading on your own!
- We do not have time to cover all of the cool and obscure things you can do with arrays.
-
We’ll be going through chunks of
demo file
slide_arrays.sh
.
Alternative Initialization
-
arr=( parentheses enumerations )
gives indices in range0
, up to but not includinglength
of array. -
Custom indices are allowed!
arr[11]=11 arr[22]=22 arr[33]=33 arr[51]="a string value" arr[52]="different string value"
-
Indices do not need to be integers:
some_array=( zero one two ) # Indices: 0, 1, 2 some_array[11]=11 # Indices: 0, 1, 2, 11 some_array["hi"]="there" # Indices: 0, 1, 2, 11, "hi"
-
You cannot have an
array
ofarray
s.
Array Functions
-
You perform an
array
operation with${expr}
- Works on non-arrays too; mandatory for arrays
-
You use the name of the variable followed by the operation:
echo "Index 11: ${arr[11]}" # prints: Index 11: 11 echo "Index 51: ${arr[51]}" # prints: Index 51: a string value echo "Index 0: ${arr[0]}" # DOES NOT EXIST! (aka nothing)
-
Like loops,
@
and*
expand differently:echo "Individual: ${arr[@]}" # Individual: 11 22 33 a string value different string value echo "Joined::::: ${arr[*]}" # Joined::::: 11 22 33 a string value different string value
-
Differently how?
echo "Length of Individual: ${#arr[@]}" # Length of Individual: 5 echo "Length of Joined::::: ${#arr[*]}" # Length of Joined::::: 5
Differently HOW?!!!
-
Easier to compare with loops
-
Remember that
;
allows you to continue on the same line.
-
Remember that
-
Individual expansion (
@
):for x in "${arr[@]}"; do echo "$x"; done # 11 # 22 # 33 # a string value # different string value
-
Joined expansion (
*
):for x in "${arr[*]}"; do echo "$x"; done # 11 22 33 a string value different string value
-
The
*
loop only executes once (everything is globbed together). -
The
@
loop iterates over each element in the array.
Even More Initialization Options
-
Evaluate expressions and initialize at once:
arr[44]=$((arr[11] + arr[33])) echo "Index 44: ${arr[44]}" # Index 44: 44 arr[55]=$((arr[11] + arr[44])) echo "Index 55: ${arr[55]}" # Index 55: 55
-
Alternative index specifications:
new_arr=([17]="seventeen" [24]="twenty-four") new_arr[99]="ninety nine" # may as well, not new for x in "${new_arr[@]}"; do echo "$x"; done # seventeen # twenty-four # ninety nine
-
Get the list of indices:
for idx in "${!new_arr[@]}"; do echo "$idx"; done # 17 # 24 # 99
Array Slicing
- You can just as easily slice your arrays.
-
Use
@
to get whole array, then specify indices to slice-
Syntax:
${array_var[@]:start_index:slice_size}
-
If
end_index
is not specified, takes until last index
-
Syntax:
zed=( zero one two three four )
echo "From start: ${zed[@]:0}"
# From start: zero one two three four
echo "From 2: ${zed[@]:2}"
# From 2: two three four
echo "Indices [2-4]: ${zed[@]:2:3}"
# Indices [2-4]: two three four
for x in "${zed[@]:2:3}"; do echo "$x"; done
# two
# three
# four
for x in "${zed[*]:2:3}"; do echo "$x"; done
# two three four
More…
ln [flags] <source> <target>
-
works like
cp
; fromsrc
todst
- creates a peer link; no notion of “original”
- only works on files
ln -s [flags] <source> <target>
-
technically the same command as
ln
, but used very differently with the -s flag! - creates a subordinate link; refers to the path. </source>
- doesn’t check to see if the source path was sensible first!
- works on files or directories.
-
awk
is a programming language designed for processing text-based data.- Allows easy operation on fields rather than full lines.
-
Works in a
pattern-action
manner, like
sed
. - Supports numerical types (and operations).
-
Supports control-flow (e.g.,
if
-else
statements).
-
Created at Bell Labs in the 1970s.
- Alfred A ho, Peter W einberger, and Brian K ernighan
-
An ancestor of
perl
, a cousin ofsed
. - K ernighan and R itchie also invent C
-
Very
powerful.
- It’s Turing Complete !
- … a lot of things are.
gawk
-
gawk
is the GNU implementation of theawk
programming language. -
On BSD/OSX, it is just called
awk
. -
On GNU, it is technically
gawk
, but should reliably be symlinked asawk
. -
There are many different implementations of the AWK programming language.
- If you use C or C++, this is similar to how there are different compilers. The compiler is an “implementation” of the language (big quotes on that…).
- If you use Python, it’s like the difference between CPython, PyPy, Jython, etc.
- Different implementations of the same programming language.
Basic Structure
-
awk
allows filters to handle text easily. -
The basic structure of an
awk
program is:pattern1 { commands1 } pattern2 { commands2 } # ...
-
Patterns can be regular expressions!
- Proceeds line by line, checking each pattern one by one.
-
If the pattern is found, the
{ commands }
are executed. -
So for the above:
- First line of input grabbed.
-
pattern1
checked, if match{ commands1 }
executed. -
pattern2
checked, if match{ commands2 }
executed. - Next line of input grabbed.
-
Check
pattern1
, thenpattern2
, so on and so forth…
-
Print all lines containing Monster or monster.
awk '/[Mm]onster/ {print}' frankenstein.txt
-
If no action specified, default is to print the whole line.
awk '/[Mm]onster/' frankenstein.txt
-
The
$0
variable inawk
refers to the whole line.awk '/[Mm]onster/ {print $0}' frankenstein.txt
-
First field (delimited by whitespace, or change field separator ).
awk '/[Mm]onster/ {print $1}' frankenstein.txt
-
awk
understands extended regular expressions by default :)-
We don’t need to escape
+
,?
, etc!
-
We don’t need to escape
-
awk
allows us blocks of code to be executed only once, at the beginning / end. -
With demo file
monstrosity.awk
and data filefrankenstein.txt
in current directory:#!/usr/bin/awk -f BEGIN { print "Starting search for monster..." } /[Mm]onster/{ count++ } # Increment if [Mm]onster found END { print "Found " count " monsters in the book." }
-
Use the
-f
in the shebang to tellawk
it expects a script.$ ./monstrosity.awk # hangs... no input file $ ./monstrosity.awk frankenstein.txt # yay! # shebang '#!/usr/bin/awk -f' makes same as ... $ awk -f monstrosity.awk frankenstein.txt
-
NF
: the number of fields in the current line. -
NR
: the number of lines read so far.-
You cannot change
NF
orNR
-
You cannot change
-
FILENAME
: the name of the input file. -
FS
: the field separator .-
Example: change
FS=","
for processing a comma-separated-value sheet. -
Can also specify
-F
flag (capital!) to set theFS
.
-
Example: change
-
awk
can match any of the following pattern types:-
/regular expression/
-
relational expression
-
pattern1 && pattern2
-
pattern1 || pattern2
-
pattern1 ? pattern2: pattern3
-
If
pattern1
, then matchpattern2
. Otherwise, matchpattern3
-
If
-
(pattern)
: parenthesis to group / change order of operations. -
! pattern
to invertpattern
-
pattern1, pattern2
: matchpattern1
, work on every line until matchespattern2
- So you cannot combine this…
-
- Regular expression usage / comparison available here .
- Many more comparison operations detailed here .
-
A wealth of useful / powerful built-in functions:
-
toupper(x)
: make string upper case -
tolower(x)
: make string lower case -
exp(x)
: exponential ofx
-
rand()
: random number between0
and1
-
length(x)
: the length ofx
-
log(x)
: returns the log ofx
-
sin(x)
: returns the sine ofx
-
cos(x)
: returns the cosine ofx
-
int(x)
: convert - etc.
-
- Much more information available here .
ifconfig [Options...]
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 40 bytes 2357 (2.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 40 bytes 2357 (2.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wlp3s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.132.6.227 netmask 255.255.128.0 broadcast 10.132.127.255
inet6 fe80::4141:aa4f:3c83:5a88 prefixlen 64 scopeid 0x20<link>
ether 00:23:15:f0:91:41 txqueuelen 1000 (Ethernet)
RX packets 97595 bytes 34824177 (33.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 69065 bytes 34033683 (32.4 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
traceroute <dest_addr>
- lists each routing hop between you and destination
- displays DNS name or IP address
dig [@
DNS server
] [
domain name
]
- gives you a lot of information behind the domain name
- includes IP address, owner, owner’s e-mail address, and more
docker image rm [IMAGE ID]
docker build -t [IMAGE NAME]
ping [flags...] <host>
- Simple echo back-and-forth
- tests connections
-
uses
ICMP
protocol – same as
traceroute
- runs forever by default
nc [flags] [host]
nc -l -p <port>
nc <host> <port>
- Raw TCP protocol tool
-
sends
stdin
over the network -
receives
stdout
from the network -
nc -l
“listens”, behaves like a server -
nc <host>
“connects”, behaves like a client
-
Installing and uninstalling:
-
Install a package:
apt-get install <pkg1> <pkg2> ... <pkgN>
-
Remove a package:
apt-get remove <pkg1> <pkg2> ... <pkgN>
-
Only one
pkg
required, but can specify many. - “Group” packages are available, but still the same command.
-
Install a package:
-
Updating components:
-
Update lists of packages available:
apt-get update
.- No arguments, it updates the whole list (even if you give args).
-
Updating currently installed packages:
apt-get upgrade
.-
Specify a
package
name to only update / upgrade that package.
-
Specify a
-
Update core (incl. kernel):
apt-get dist-upgrade
.
-
Update lists of packages available:
-
Searching for packages:
-
Different command:
apt-cache search <pkg>
-
Different command:
-
Installing and uninstalling:
-
Install a package:
dnf install <pkg1> <pkg2> ... <pkgN>
-
Remove a package:
dnf remove <pkg1> <pkg2> ... <pkgN>
-
Only one
pkg
required, but can specify many. -
“Group” packages are available, but different command:
-
dnf groupinstall 'Package Group Name'
-
-
Install a package:
-
Updating components:
-
Update EVERYTHING:
dnf upgrade
. -
update
exists, but is essentiallyupgrade
.-
Specify a
package
name to only upgrade that package.
-
Specify a
-
Updating repository lists:
dnf check-update
-
Update EVERYTHING:
-
Searching for packages:
-
Same command:
dnf search <pkg>
-
Same command:
-
yum
anddnf
(Dandified Yum
) nearly interchangeable: [Wallen 2015 ] .
-
Installing and uninstalling:
-
Install a
formula
:
brew install <fmla1> <fmla2> ... <fmla2>
-
Remove a formula:
brew uninstall <fmla1> <fmla2> ... <fmlaN>
-
Only one
fmla
required, but can specify many. -
“Group” packages have no meaning in
brew
.
-
Install a
formula
:
-
Updating components:
-
Update
brew
, all taps , and installed formulae listings. This does not update the actual software you have installed withbrew
, just the definitions:brew update
. -
Update just installed formulae:
brew upgrade
.-
Specify a
formula
name to only upgrade that formula.
-
Specify a
-
Update
-
Searching for packages:
-
Same command:
brew search <formula>
-
Same command:
- There are so many package managers out there for different things, too many to list them all!
-
Ruby:
gem
-
Anaconda Python:
conda
-
Python:
pip
-
Python:
easy_install
(but really, just usepip
) -
Python3:
pip3
-
LaTeX:
tlmgr
(uses the CTAN database)-
Must install TeX from source to get
tlmgr
-
Must install TeX from source to get
-
Perl:
cpan
-
Sublime Text:
Package Control
- Many many others…
chroot <dir> <command>
- Must execute as root
-
hides filesystem below
<dir>
-
dir
looks like new/
-
Installing and uninstalling:
-
Install a package:
apt install <pkg1> <pkg2> ... <pkgN>
-
Remove a package:
apt remove <pkg1> <pkg2> ... <pkgN>
-
Only one
pkg
required, but can specify many. - “Group” packages are available, but still the same command.
-
Install a package:
-
Updating components:
-
Update lists of packages available:
apt update
.- No arguments, it updates the whole list (even if you give args).
-
Updating currently installed packages:
apt upgrade
.-
Specify a
package
name to only update / upgrade that package.
-
Specify a
-
Update core (incl. kernel):
apt dist-upgrade
.
-
Update lists of packages available:
-
Searching for packages:
-
Different command:
apt-cache search <pkg>
-
Different command:
-
Installing and uninstalling:
-
Install a package:
dnf install <pkg1> <pkg2> ... <pkgN>
-
Remove a package:
dnf remove <pkg1> <pkg2> ... <pkgN>
-
Only one
pkg
required, but can specify many. -
“Group” packages are available, but different command:
-
dnf groupinstall 'Package Group Name'
-
-
Install a package:
-
Updating components:
-
Update EVERYTHING:
dnf upgrade
. -
update
exists, but is essentiallyupgrade
.-
Specify a
package
name to only upgrade that package.
-
Specify a
-
Updating repository lists:
dnf check-update
-
Update EVERYTHING:
-
Searching for packages:
-
Same command:
dnf search <pkg>
-
Same command:
-
yum
anddnf
(Dandified Yum
) nearly interchangeable: [Wallen 2015 ] .
-
Installing and uninstalling:
-
Install a
formula
:
brew install <fmla1> <fmla2> ... <fmla2>
-
Remove a formula:
brew uninstall <fmla1> <fmla2> ... <fmlaN>
-
Only one
fmla
required, but can specify many. -
“Group” packages have no meaning in
brew
.
-
Install a
formula
:
-
Updating components:
-
Update
brew
, all taps , and installed formulae listings. This does not update the actual software you have installed withbrew
, just the definitions:brew update
. -
Update just installed formulae:
brew upgrade
.-
Specify a
formula
name to only upgrade that formula.
-
Specify a
-
Update
-
Searching for packages:
-
Same command:
brew search <formula>
-
Same command:
- There are so many package managers out there for different things, too many to list them all!
-
Ruby:
gem
-
Anaconda Python:
conda
-
Python:
pip
-
Python:
easy_install
(but really, just usepip
) -
Python3:
pip3
-
LaTeX:
tlmgr
(uses the CTAN database)-
Must install TeX from source to get
tlmgr
-
Must install TeX from source to get
-
Perl:
cpan
-
Sublime Text:
Package Control
- Many many others…
References
ASCII Table . 2010. ASCII character codes and html, octal, hex, and decimal chart conversion. http://www.asciitable.com/ .
Bash Reference Manual . 2017a. Bash reference manual: Pattern matching. http://www.gnu.org/software/bash/manual/bashref.html#Pattern-Matching .
Bash Reference Manual . 2017b. Bash reference manual: Shell parameter expansion. https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html .
Computer Hope . 2016. Linux and unix chmod command help and examples. http://www.computerhope.com/unix/uchmod.htm .
The Linux Documentation Project . 2017a. Exit codes with special meanings. http://tldp.org/LDP/abs/html/exitcodes.html .
The Linux Documentation Project . 2017b. Introduction to if. http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html#sect_07_01_01 .
The Linux Documentation Project . 2017c. Globbing. http://www.tldp.org/LDP/abs/html/globbingref.html .
The Linux Documentation Project . 2017d. Special characters. http://www.tldp.org/LDP/abs/html/special-chars.html .
Wallen, J. 2015. What you need to know about fedora’s switch from yum to dnf. https://www.linux.com/learn/tutorials/838176-what-you-need-to-know-about-fedoras-switch-from-yum-to-dnf .
Wikipedia . 2017. Redirection (computing). https://en.wikipedia.org/wiki/Redirection_%28computing%29 .
Wooledge, G. 2015. Configuring your login sessions with dot files. http://mywiki.wooledge.org/DotFiles .