
Unix Tricks - dedalus
http://cfenollosa.com/misc/tricks.txt
======
Tepix
Missing trick:

In bash, "ESC" then "." fetches the last parameter of the previous command.
It's invaluable (same as typing "!$" but you get to see and edit it)

~~~
lloeki
It's actually _Meta_ , emulated by an ESC character by the terminal. OSX tip:
check _" use Option as Meta"_ in Terminal's preferences, and you can keep
_Option_ pressed while you mash ".".

~~~
akirk
Which is fine if you never need to generate characters using the Option key.
For example on a German keyboard you need the Option key to write { or }.

~~~
lloeki
I'm on a french layout so I know :-)

It also has the side effect of "resurrecting" dead keys (which are unrelated
to Option), making input of 'ê'and 'ï' impossible.

An alternative is using iTerm2 which has a similar setting, liberally
applyable to _either_ Option key.

------
wazoox
Ctrl+r is fine when you're looking for something recent, but this one is
useful when you're looking through a long list of similar commands.

    
    
        alias hist='history  | grep'
    

Use it like this:

    
    
        $ hist git
          9543  git add toto
          9544  git commit
          9545  git log
          9546  git log
          9548  git add -A
          9549  git commit
          9550  git log
          9633  git pull
          9955  cd dev/git
          9957  git grep copyof
          9958  git grep copyof
          9959  git pull
    

By the way, do you know you can call back the 9633rd command in the history
with "!9633"?

~~~
WickyNilliams
I use this all the time. In fact it was one of the first aliases i made when i
switched to a UNIX system. Though I named mine `greph` (for grep history).
Absolutely invaluable

------
valarauca1
Its implied on the list but not mentioned specifically.

    
    
         !! 

will be substituted with the last command you typed. So if your somebody like
me who frequently types

    
    
         $ apt-get update
         Could not lock yada yada are you root?
         $ sudo apt-get update
    

instead you can type

    
    
         $ apt-get update
         $ sudo !!

~~~
cheepin
What I love about this is that if you up-arrow through your past commands, the
"sudo !!" shows up as "sudo apt-get update"

~~~
valarauca1
Bash substitutions are done prior to execution so your history stays intact.
Older open source projects are just amazing for how complete their feature set
is.

~~~
pokpokpok
is this how people feel about religious texts?

~~~
valarauca1
Originally I was gonna write:

>Religious texts don't change over time due to community suggested changes.

Then I caught myself.

------
3rd3

        man hier
    

is pretty cool. It explains the root directory structure of the system.

~~~
ciupicri
Which was updated just yesterday[1].

[1]:
[https://plus.google.com/+LennartPoetteringTheOneAndOnly/post...](https://plus.google.com/+LennartPoetteringTheOneAndOnly/posts/GnZhvjHmZxw)

~~~
agumonkey
international pun, hier being french for yesterday.

------
curiousHacker
You know what I hate? My history isn't aggregated in real time across all my
Mac OS X terminal windows.

You know what else I hate? Typing in long commands in the Mac OS X terminal
and then them wrapping weirdly. Especially when I hit the up arrow to go back
in my terminal history.

~~~
Tiksi
Here you go, just throw it in your .bashrc:

    
    
      shopt -s histappend
      export HISTSIZE=100000
      export HISTFILESIZE=100000
      export HISTCONTROL=ignoredups:erasedups
      export PROMPT_COMMAND="history -a;history -c;history -r;$PROMPT_COMMAND"
    

I wish I could give credit to where I originally found this but it was ages
ago.

~~~
gknoy
I've been using `history -a`, but what do `history -c` and `history -r` do?

It looks like it clears your shell's history, and then re-populates it from
the .bash_history file?

~~~
Flenser

       history -a  # append history lines from this session to the history file.
       
       #History file may contain history from other terminals not in this one so:
    
       history -c # clear [in-memory] history list deleting all of the entries.
       history -r # read the history file and append the contents to the history list instead.
    

I've heard that -n can be problematic which is why -c then -r is used.

------
samsaga2
It's amazing how many years I've been using bash and I still have things to
discover.

Ctrl-x Ctrl-e nice tip!

~~~
pling
I still prefer "sh" on BSD (particularly OpenBSD). It doesn't have as many
knobs to turn nor as many surprises.

~~~
currysausage
sh, the Bourne shell mode of pdksh? Isn't that a little too limited? pdksh
(/bin/ksh) though is great, yes.

I'm in general a big fan of the OpenBSD userland: straightforward and very,
_very_ well-documented. Real manpages, no religious "The full documentation
for xyz is maintained as a TeXinfo manual" crap.

A well-conceived featureset and good docs are key to properly learning a
platform. OpenBSD taught me a lot about Unix. If you later realize that Bash
has some feature that you actually need, you can still install it.

~~~
Zenst
Also worth noting that native borne shell was always slightly slower than korn
shell. Though been a long time since I checked that one out, though did on few
systems and found it to be so. But there again csh was also about then,
distant memory in for many that one.

Also anything that will run script wise on bourne will run as is under korn.

Though you may well find that it is historical, which one a user picks shell
wise. People who started or worked a lot with Sun systems will be csh fans.
Old vets more inclided to bourne, though very few. As for korn shell, that
would be mostly down to AIX systems as that is the default upon them as with
the other systems mentions, default wise. Then for Linux you will find a bias
towards bash.

Least that is what I have observed.

Though history does give us some intersting trends and the awk, perl, python
transition and preference will also mostly be down to when somebody got into
unix as a whole. Again old school, awk. Old, perl and not so long ago the
python brigade.

But that is just a rule in thumb and more helpful in explaining why there is a
solo perl script when everything else done in xyzzy type encounters.

As for OpenBSD, good choice, I prefer it due to the file system layout and
more akin to old school unix unlike Linux which is `creative` more than not in
choices, so feels less at home.

Still back in the early days we had AT&T and Berkly BSD flavours and with that
the ps command, oh the fun and games.

But least thinks a little bit more common across flavours than before and yet
still each has there own quirks.

~~~
pling
I think shell performance stopped mattering the moment I dumped my 50MHz SPARC
LX for a Sun Ultra 2.

~~~
Zenst
Very true, but in production, every nanosecond counts sometimes.

------
danielweber
> \- 'sort | uniq' to check for duplicate lines

sort -u

------
WickyNilliams
A personal favourite of mine is aliasing common cd operations.

    
    
        alias ..="cd .."
        alias ...="cd ../.."
        # etc
    

and of course `cd -` to jump to previous directory

------
dorfsmay
> In bash, 'ctrl-r' searches your command history

No! In _emacs_ ctrl-r searches your command history. It happens that bash use
emacs mode by default. All other emacs basic commands work too: ctrl-p,
ctrl-n, ctrl-f etc...

If you are a vim user, and especially if you love venting how much you hate
emacs, then please add this to your bashrc:

set -o vi

and now you can use vim command instead of emacs.

~~~
dllthomas
'ctrl-r' is reverse-i-search in vi mode as well.

~~~
dventimi
'ctrl-r' is bound to isearch-backward in my Emacs.

'meta-r' is bound to comint-history-isearch-backward-regexp

------
nemasu
I actually bookmarked a similar page a little while ago, super useful:
[http://www.reddit.com/r/linux/comments/21rm3o/what_is_a_usef...](http://www.reddit.com/r/linux/comments/21rm3o/what_is_a_useful_linux_tool_that_you_use_that)

------
lloeki
Instead of

    
    
        ssh -R 12345:localhost:22 server.com "sleep 1000; exit"
    

use

    
    
        ssh -R 12345:localhost:22 -n server.com
    

The -n flag tells ssh to only make a connection, without ever running a shell.
This means it even works when you don't have shell access (say, with a
_command=_ entry in _.authorized_keys_ ).

Also, I cannot recommend _envoy_ enough in lieu of _ssh-agent_ , if you're not
using a GUI ssh agent already (e.g OSX keychain or GNOME keyring)

Last, I guarantee you don't want "$@" in those aliases, but either "$*" or $@
(certainly the latter).

~~~
ciupicri
I think you meant _-N_ , not _-n_. From the man page[1]:

    
    
         -N      Do not execute a remote command.  This is useful for just for‐
                 warding ports (protocol version 2 only).
    
         -n      Redirects stdin from /dev/null (actually, prevents reading from
                 stdin).  This must be used when ssh is run in the background.
    

[1]: [http://www.openbsd.org/cgi-
bin/man.cgi?query=ssh&sektion=1](http://www.openbsd.org/cgi-
bin/man.cgi?query=ssh&sektion=1)

------
voltagex_
I wonder if I can convince the author of this to put it up in a Git repo so
everyone can contribute. It probably needs the tiny URLs removed (IME, they're
more likely to break than the original site)

------
TimWolla
You might want to try out the more modern fish shell as well:
[http://fishshell.com/](http://fishshell.com/) It makes history searching even
easier.

~~~
bshimmin
I love fish and have happily been using it for years. Every time it comes up
here, though, someone inevitably will complain about compatibility - and I
will admit that RVM, for instance, has definitely caused me problems with fish
in the past. I guess it depends quite a lot on your particular usage and
requirements.

~~~
robin_reala
I never got RVM working with fish; unsurprising, seeing as it’s 20k lines of
bash. rbenv works well though (with one additional conf line), and chruby was
working on support last time I checked.

~~~
bshimmin
There's a wrapper to get RVM working with fish, in case it matters to you now;
details here:
[https://rvm.io/integration/fish](https://rvm.io/integration/fish)

~~~
robin_reala
Doesn’t matter now :) rbenv does everything I need in a lighter package.

------
currysausage
I found Ctrl-O (execute current command from history and edit the next one) to
be invaluable.

Ctrl-V: type next input literally (e.g. Ctrl-V [Tab] if you don't want [Tab]
to autocomplete).

Alt-#: Prefix current line with "#" (don't execute it) and put it into history
for later use.

I'm sometimes surprised how many people don't know these: Ctrl-U/K: kill line
before/after cursor.

------
chanux
Pipe to clipboard with following alias

alias clip='xsel -i --clipboard'

Get tree view of directories

alias lst='tree -L 2 $1'

Also I use za to go up in directory tree

bash
[https://gist.github.com/chanux/1119556](https://gist.github.com/chanux/1119556)
fish
[https://gist.github.com/chanux/9411092](https://gist.github.com/chanux/9411092)

------
thln666
"\- Compile your own version of 'screen' from the git sources. Most versions
have a slow scrolling on a vertical split or even no vertical split at all"

Or you could just use tmux which afaict is superior to screen in almost every
way. [http://tmux.sourceforge.net/](http://tmux.sourceforge.net/)

------
pmontra
I suggest bashmarks
[http://www.huyng.com/projects/bashmarks/](http://www.huyng.com/projects/bashmarks/)
to bookmark directories and jump there with a quick command. I also like to
alias ..="cd .." and alias ...="cd ../.." to quickly navigate up.

------
rzimmerman
Ctrl-R is by far the most useful one for me.

~~~
cmatteri
The article doesn't say, so it's worth mentioning that you can type ctrl-R
multiple times to search further back into command history.

~~~
danielweber
I use C-r constantly. But sometimes I need to find a command, and then edit it
before running it. What is the proper way to exit "search mode" and go into
the normal "edit" mode?

~~~
morsch
Any movement key will do the trick. I usually use cursor-right or the end key.

It's so ingrained I had to actually do it in a shell to know what it was I
did.

~~~
danielweber
ISTR pressing one of those keys would obliterate the part of my line where I
was writing, putting in ^B characters.

I can't replicate it now on my test box; it works exactly the way you say it
should. It may be a terminal issue; I'm currently on Windows using cygwin to
ssh to Linux.

------
o_____________o
I was going to write a shell package/snippet manager until I discovered this:

[https://github.com/ziyaddin/jean](https://github.com/ziyaddin/jean)

It would be nice to get all of these .bash_profile enhancements in as
packages.

I suppose it could be improved to prompt for a brew/apt install if needed.

------
marcosscriven
A really handy one a colleague showed me yesterday was the /dev/fd/0|1|2
files, which are stdin/out/err respectively. Means you can use that file for
utils that expect a file only.

E.g echo "This would be contents of file" | someCommand /dev/fd/0

~~~
LukeShu
These are also available as /dev/std{in,out,err}; the names of which are a
little more self documenting :)

    
    
        $ ls -l /dev/fd /dev/std* | column -t
        lrwxrwxrwx  1  root  root  13  Jun  27  16:32  /dev/fd      ->  /proc/self/fd
        lrwxrwxrwx  1  root  root  15  Jun  27  16:32  /dev/stderr  ->  /proc/self/fd/2
        lrwxrwxrwx  1  root  root  15  Jun  27  16:32  /dev/stdin   ->  /proc/self/fd/0
        lrwxrwxrwx  1  root  root  15  Jun  27  16:32  /dev/stdout  ->  /proc/self/fd/1
    

You can even access the file descriptors of other processes with
/proc/${pid}/fd/; which is handy for (say) un-deleting a file that a process
still has open.

Another handy one is "process substitution" which lets you do the same thing
with multiple streams by creating new file descriptors, and automatically
turning them into /dev/fd/* paths:

    
    
        someCommand <(echo "contents of file 1") <(echo "contents of file 2")
    

which is somewhat explained by:

    
    
        $ echo someCommand <(echo "contents of file 1") <(echo "contents of file 2")
        someCommand /dev/fd/63 /dev/fd/62

~~~
toddkaufmann
"process substitution" is one of the new useful things I learned this year
(switched to bash from csh over 20 years ago).

/proc/${pid}/fd/ is very useful for forensic purposes when you find some
malware running that deleted itself and/or config files but still has a handle
open to them.

------
kneth
Now and then I reread a chapter of "Classic Shell Scripting"
([http://shop.oreilly.com/product/9780596005955.do](http://shop.oreilly.com/product/9780596005955.do))
- probably the best book on shell script I know.

------
jlas
Along with the !! function you can reference the last call of a specific
command like so:

    
    
        !<cmd>
    

e.g. sometimes I forget the "ln -s" order of arguments (to which it gives me
an error), so I follow it up with:

    
    
        ln -s !ln:3 !ln:2

------
agumonkey
I used to be excited about this, now I found it shallow. Better unix tip =>
[http://www.confreaks.com/videos/615-cascadiaruby2011-the-
uni...](http://www.confreaks.com/videos/615-cascadiaruby2011-the-unix-
chainsaw)

------
fauria
I would add:

    
    
        TOOLS
        ...
        * 'tree' instead of 'ls -R'
        ...

~~~
voltagex_
Which package would that be in?

~~~
ejstronge
On Debian/Ubuntu, you can use the `apt-file` package to determine what package
a file resides in. For example:

    
    
        apt-file search /bin/tree

------
scarygliders
Another one:

Use dcfldd instead of dd if you want to see how far your dd operation is
progressing...

dcfldd if=[infile] of=[outfile] sizeprobe=if

So. Much. Better.

dcfldd also has many other useful options - read the man pages - and note that
you'll have to install it from your linux distro's package repo beforehand.

~~~
sushimako
You can also send SIGUSR1 to dd for progress info. From the manpage:

    
    
      Sending a USR1 signal to a running 'dd' process makes it print I/O statistics to standard error and then resume copying.
    
        $ dd if=/dev/zero of=/dev/null& pid=$!
        $ kill -USR1 $pid; sleep 1; kill $pid
    
        18335302+0 records in 18335302+0 records out 9387674624 bytes (9.4 GB) copied, 34.6279 seconds, 271 MB/s

~~~
sneak
Caution: while this works great on Linux, on OSX, a USR1 will kill dd, and a
SIGINFO will get you the block counts.

~~~
staticshock
Indeed, looks like GNU coreutils dd responds to SIGUSR1 on linux and SIGINFO
on linux. That's good to know. What's the reason for this discrepancy?

~~~
dankm
OSX inherited SIGINFO from the BSDs, OpenBSD, FreeBSD, Dragonfly, and NetBSD
all have it.

Linux doesn't. I don't know why; but Google in the past has told me that
patches to add it were rejected about 10 years ago.

------
aceperry
>Don't know where to start? SMB is usually better than NFS for most cases.

Not sure why he feels SMB is better, because in my experience, NFS usually
works more smoothly and is easier to setup than SMB. But then, I don't usually
use windows.

------
nemasu
One to add: Unfreezing terminal after pressing Ctrl+S by accident. Press
Ctrl-Q.

~~~
danielweber
One that I needed to use a lot in the old days, and still occasionally need:

If your font is all messed up, echo C-v C-o. C-v puts you into a literal mode,
and C-o gets you back into the normal character set. (You probably got there
by emitting a C-p at some point.)

~~~
mkesper
I always used 'reset' for that.

------
AssertFailure
Instead of using netcat when tunneling SSH through another machine like this:

    
    
        ProxyCommand ssh -T host1 'nc %h %p'
    

one should use this instead:

    
    
        ProxyCommand ssh -W %h:%p host1

~~~
aseidl
The only problem with -W is that it is not available everywhere yet: RHEL6
defaults to OpenSSH 5.3, while -W was introduced in 5.4. Thankfully EL7 comes
with OpenSSH 6.4 (and a kernel newer than 2.6.32!).

------
k4rthik
I have

for cmd in $(compgen -c); do if [[ $cmd =~ ^[0-9a-zA-Z]+$ ]]; then eval "alias
$cmd?='man $cmd'"; fi; done

in my .bashrc to alias command?=man command, saves some typing to get to man
pages ( which I do very often )

~~~
vram22
Speaking of man pages, in earlier versions of Unix and Linux, I used to want
to redirect the output of many man commands to files for later reading, e.g.
if working on C, say I wanted to read 'man ioctl', 'man stdio', 'man signal',
etc. But the man output had {n|t}roff formatting characters in it, for print
output, which used to mess up vi. So I used to use this script I wrote, called
m:

# Put this script in a directory in your PATH.

# m: pipe man output through col and save to file(s).

mkdir -p ~/man # Only creates the dir first time, including all dirs in the
path.

for name: # in $* is implied

    
    
        man $name | col -bx > ~/man/$name.m
    

done

Do a "chmod u+x m" to be able to run it.

Then run it like this:

m ioctl stdio signal # or any other commands

Then:

pushd ~/man; view ioctl.m stdio.m signal.m; popd

to read those pages, now stripped of formatting characters.

------
biftek
zsh has a simple builtin `r` (which is just an alias for `fc -e -`). It lets
you edit the previous command with search and replace. I use it for brew and
git a lot.

    
    
      $ brew info rust
      $ r fo=stal

------
jalanb
I notice j.py in that list. I forked that a wee while back, and have been
enhancing it ever since:

[http://www.al-got-rhythm.net/kd/](http://www.al-got-rhythm.net/kd/)

~~~
grimgrin
[https://github.com/rupa/z](https://github.com/rupa/z) is really nice, too.
Pure bash.

------
atoponce
[http://www.commandlinefu.com/commands/browse/sort-by-
votes](http://www.commandlinefu.com/commands/browse/sort-by-votes)

------
Zenst
stty - sane

Very handy if you do something silly like cat a binary file without piping it
into strings -a

This restores the terminal settings and sanity restored. Note you will often
find yourself typing without seeing anything, least until you enter and
execute the sane.

Also asvise the following usage ctrl+c a couple of times to clear anything out
of the input buffer queued up. stty -sane all good from here onwards and good
time to play with od and remember the strings -a pipe next time.

------
andrey-p
I love these, there's too much to process but I always get to learn at least
one ridiculously useful thing. Today's was vim's `:set spell`.

------
cellover
Very interesting resource! It's amazing to see how after 10 years of using
command line that you can learn new tricks. Every single day!

------
INTPenis
I call this one sshping.

    
    
        while sleep 0.1; do nc -w 1 -z host 22; done
    

Useful when waiting for systems to boot.

~~~
lloeki
Add this line to (vixie) cron:

    
    
        @reboot /bin/date | /usr/bin/mail -s "$(/bin/hostname) booted" root@example.com
    

If you don't want to configure postfix as a smarthost (which is not _that_
hard and recommended if only to have mail queued for retry), use ssmtp.

------
dorfsmay
> 'htop' instead of 'top'

meh, I don't like htop. "atop" on the other hand!!!

------
wombit
[http://explainshell.com/](http://explainshell.com/)

------
gowan
Send a command to display 1.

`xterm -display :1 -e <command>`

This is useful when running automated tests on top of vnc.

------
ing33k
one more resource [http://www.thegeekstuff.com/2010/11/50-linux-
commands/](http://www.thegeekstuff.com/2010/11/50-linux-commands/)

------
xr09
j.py? The original is autojump:
[https://github.com/joelthelion/autojump/](https://github.com/joelthelion/autojump/)

~~~
grimgrin
z is a nice replacement that is purely written in bash.

[https://github.com/rupa/z](https://github.com/rupa/z)

------
meapix
!.

------
sigsergv
And for python3:

python3 -m http.server 8080

