
What's the one Linux command you wish you knew years ago? - roadnottaken
http://www.reddit.com/r/linux/comments/mi80x/give_me_that_one_command_you_wish_you_knew_years/
======
mmaunder
Actually the new top comment blew me away. I'm in the 20 year veteran category
and was also oblivious. Quoted:

disown - bash built in.

You know how you always start that mega long rsync in an ssh session from your
laptop and then realize you have to go offline halfway through? You forgot to
start it in screen or nohup, didn't you? You can pause it (ctrl+z), background
it (bg), and then disown it so it is protected from SIGHUP when you quit your
ssh session. Bash (and, to be fair, zsh and others have copied much of this)
has some wonderful job control features most people are completely oblivious
of - even veterans of 20 years.

~~~
sgt
disown is great. However, I don't know if it's possible to start up a new
shell, then bring back that process to the foreground. 'jobs' will return no
entries, and fg doesn't take a PID parameter. Any ideas? It would be brilliant
if that were possible with bash alone.

~~~
tel
Screen is the only real answer, I've ever found.

~~~
gnosis
There's also 'tmux':

<http://tmux.sourceforge.net/>

~~~
dredmorbius
Which according to reports has the benefit of being maintainable.

GNU screen, which I love and use to obscene extents daily, has an
exceptionally hairy codebase. That said, I've got to get my tmux on and learn
how to do screen equivalents with it....

[http://www.techrepublic.com/blog/opensource/is-tmux-the-
gnu-...](http://www.techrepublic.com/blog/opensource/is-tmux-the-gnu-screen-
killer/1901)

~~~
res0nat0r
I keep seeing people comment on the codebase of screen being bad vs tmux, but
I'm not sure why that is an issue? Are there any features of screen missing
that haven't been added to the codebase? The vertical split patch has been
added a long while back, and even though I'm sure tmux has a smaller memory
footprint, I've never had an occasion where screen has ever been an app I'm
worried might impact my server memory usage.

Since it is installed for the most part everywhere I have no desire to switch
to tmux.

~~~
leif
FWIW, I've switched to tmux but think tmux's implementation of split screen is
broken and desperately miss screen's.

Screen lets each part of a split screen select a different existing window.
Tmux makes both parts of a split part of a single window, so you can either
have two things going in one split, or have something else going on in another
window, but if you suddenly decide you want two existing windows side by side,
you can't do it.

------
PascalW
Not really a command but this:

    
    
      mv /path/to/some/file.{jpg,png}
    

Has been a huge timesaver. It's the same as

    
    
      mv /path/to/some/file.jpg /path/to/some/file.png
    

But saves you the typing/copy pasting the path for the second argument. Can
also be used with cp etc.

~~~
bgaluszka
Either that or

    
    
        rename jpg png /path/to/some/file.jpg

~~~
robertskmiles
I didn't know you could do that with rename. I would have done

    
    
        rename 's/jpg/png/g' /path/to/some/file.jpg

~~~
tweakism
These are actually two different "rename" commands. bgaluszka's version is
usually found on Fedora/RHEL/etc. systems coming from the util-linux package,
while your version is usually found on Debian/Ubuntu/etc. systems coming from
the Perl package.

I prefer the regex one, of course, especially since it takes proper Perl
regexes :)

You have to be careful of this though and probably avoid using this command in
shell scripts.

edit: You can just stick Debian's rename at $HOME/bin/rename.pl and call it a
day; this command is useful in the terminal since it's less typing than a for
loop.

------
mrb
Nobody knows this: the bash extension <(cmd) to pass the output of a command,
as if it was a file, to another command. Example to diff the list of files in
2 directories (a and b) without using temporary files:

    
    
      $ diff -u <(cd a && find . | sort) <(cd b && find . | sort)
    

Internally, bash creates a pipe and passes /dev/fd/XXX to the main command.

~~~
sixtofour
Just diff the two directories.

    
    
        $ ls a b
        a:
        1  2  3  4
        
        b:
        1  2  3
        
        # Yours:
        $ diff -u <(cd a && find . | sort) <(cd b && find . | sort)
        --- /dev/fd/63	2011-11-20 02:50:21.919072726 -0700
        +++ /dev/fd/62	2011-11-20 02:50:21.919072726 -0700
        @@ -2,4 +2,3 @@
         ./1
         ./2
         ./3
        -./4
        
        # Mine:
        $ diff -u a b
        diff -u a/1 b/1
        --- a/1	2011-11-20 02:43:57.073130007 -0700
        +++ b/1	2011-11-20 02:45:14.535912768 -0700
        @@ -1 +1 @@
        -1
        +11
        Only in a: 4
    

Maybe I'm missing something?

~~~
jav
The OP's example is diffing listings of the two directories whereas your
command is asking diff to directly work on the directories themselves.

~~~
robertskmiles
Which means for example you could get that listing in any format, so you could
for example spot changes in permissions or ownership if you included it in the
listing.

~~~
sixtofour
I stand enlightened.

------
mmaunder
100% agree with CTRL-R. It changed my life. Others that I love:

screen, pdsh,

perl -pi -e 's/find/replace/g' *.txt

redis-cli's new ability to have piped in data be the last argument of a
command.

vim -o file1.txt file2.txt file3.txt (opening multiple files with vim)

Using vim instead of less as a pager: cat file.txt | vim -

~~~
sixtofour
<http://www.vim.org/scripts/script.php?script_id=1723>

vimpager. Set vim _as_ your pager. I love reading man pages in syntax-colored
vim glory.

~~~
dredmorbius
I prefer keeping file viewing and file editing as separate actions.

'most' will colorize bash output as well (it's strictly a pager, in the pg /
more / less / most continuum).

~~~
sashahart
As I recall, vimpager doesn't edit files, it just uses vim to view the file
instead of using a different program to view the file.

------
scrrr
My method to learn Linux/OSX command line.

Step 1: Think "I wish I could do X."

Step 2: Google/duckduckgo "How to do X in bash"

Step 3: Delight that a simple solution already exists.

This method is successful in 95% of all cases.

~~~
dhughes
This post and probably your comment will be in the results , gotta love that.

------
tikhonj
For me it was definitely find. I went through a ton of contortions to
replicate its behavior several times before somebody knowledgeable clued me
in.

Also, `` and $(). Find combined with one of these is great. One of my favorite
one-liners (I even figured it out myself :)) is:

    
    
        cat `find . --name *.java` | wc -l

~~~
sbov
Never thought to use ``. I always used xargs:

find . -name *.java | xargs cat | wc -l

~~~
cperciva
Your approach works better than backtick expansion, since it won't run into
'command line too long' issues; but it will still break on "weird" file names
(e.g., file names with spaces in them). The correct way to do this is

    
    
        find . -name *.java -print0 | xargs -0 cat | wc -l

~~~
pyre
xargs can still run you into the 'too many args' issue. You'll want to use
this:

    
    
           --max-args=max-args
           -n max-args
                  Use  at  most max-args arguments per command
                  line.  Fewer than max-args arguments will be used
                  if the size (see the -s option) is exceeded,
                  unless the -x option is given, in which case xargs
                  will exit.

~~~
cperciva
Only if there's a bug in your xargs. POSIX states:

 _The xargs utility shall limit the command line length such that when the
command line is invoked, the combined argument and environment lists (see the
exec family of functions in the System Interfaces volume of POSIX.1-2008)
shall not exceed {ARG_MAX}-2048 bytes_

so you should never run into the ARG_MAX limit.

------
dkubb
pv - very useful to put in the middle of a series of piped commands to provide
feedback on what, if anything, is happening.

I could've used this many times to catch cases where the amount of work being
performed didn't match my expectations; usually an indication of an incorrect
assumption or mistake I had made. Instead I sat there waiting for something
way longer than I should've, only because I had a bad feedback loop.

------
chimeracoder
I'm not sure why, but it was a while before I ran across du -h. Not sure how I
ever did without it!

Oh, and "sudo !!". Definitely key, along with "& disown".

~~~
re_todd
"!ssh" to run the most recent ssh command without having to type out the long
list of arguments I use and the host name.

~~~
steve-howard
It helps to put your most frequent entries in ~/.ssh/config

    
    
      Host somewhere
      HostName somewhere.example.com
      User username
      IdentityFile ~/.ssh/somewhere_key.pub

~~~
bnegreve
yes and do you know about _proxycommand_ ?

let you set up hops when you don't have direct access to a server.

e.g. if you don't have direct access to serverB but have direct access to a
serverA that has direct access to serverB

put this in your ~/.ssh/config file

    
    
      host serverA
      hostname serverA.domainname.com
    
      host serverB
      hostname serverB.domainname.com
      ProxyCommand ssh serverA "nc %h %p"
    

then typing ssh serverB will log you on serverB

------
diiq
That reddit thread is delightful, because it is full of wonderful commands
that I didn't know, or rarely use, or had forgotten.

But it's also terrifying, because it exposes how many people will post
questions before using man.

~~~
p9idf
Many comments seem to be shell- and bash-related. Perhaps the thread exposes
how difficult to read the bash manpage is. On my system, the bash 4.1 manpage
is 41026 words long, or about 80 pages. Manpages are most useful to me when
they are short and to-the-point so I can find what I am looking for before I
lose interest in skimming through an 80 page book.

~~~
huskyr
I'm baffled all the time by the lack of clear examples on many manpages.

~~~
morsch
Yep, a short list of useful one-liners would go a _long_ way. Often, your use-
case will be a straight specialisation of one of the examples, and if not,
chances are you can cobble together something from several examples. I'd like
to have a auxiliary help command for this, e.g. _example ffmpeg_ in addition
to _man ffmpeg_ (another 18k words manpage).

Edit: This works rather well:

    
    
      function cmdfu() {
             curl "http://www.commandlinefu.com/commands/matching/$@/$(echo -n $@ | openssl base64)/plaintext" --silent | sed "s/\(^#.*\)/\x1b[32m\1\x1b[0m/g"
      }
    

From [http://www.commandlinefu.com/commands/view/3086/search-
comma...](http://www.commandlinefu.com/commands/view/3086/search-
commandlinefu.com-from-the-command-line-using-the-api#comment), it uses the
commandlinefu API: <http://www.commandlinefu.com/site/api>

~~~
JonWood
Another alternative is <a
href="[http://cheat.errtheblog.com/>Cheat</a>](http://cheat.errtheblog.com/>Cheat</a>),
which is essentially a CLI accessible wiki of usage examples. It was
originally focused on Ruby (and still is to an extent), but it gives decent
results a lot of the time.

------
ludwigvan
emacs --daemon

(or after you start emacs, M-x server-start). This starts up the emacs server,
so that it preserves your open files, and you can start new emacs instances
immediately with emacsclient. (I actually symlink emacsclient to vi since it
loads as fast as vi, which was one of the weakest points of emacs for me.)

Very useful if you are using a remote box (like a vps) as your dev
environment.

~~~
pja
In my .bashrc I have:

    
    
      export ALTERNATE_EDITOR=''
      alias e='emacsclient -t'
    

Now

    
    
      $ e file.txt
    

will fire up emacsclient to connect to a running emacs daemon. If there is no
emacs daemon running it will start one for you and then connect to it.

You can

    
    
      export VISUAL="emacsclient -t"
      export EDITOR='emacsclient -t'
    

for good measure if you like.

------
Maven911
_watch_ for not having to repeatdly type a comnand, usually for an sw app
_stat_ for checking when a files been accessed

 _tee_ piping to a log file with tee, while still seeing normal stdout on
screen

~~~
spudlyo
I love the _watch_ command too. I really enjoy it with -d (delta or
differences) which will highlight what changed since the last run.

------
matheusalmeida
It's not a command but it is still useful. When you are typing a long command
and you realize that you need to do other command or set of commands first,
usually you type ctrl + c to cancel it. By default it does not save in the
history. If you put # (comment the command) in front of the command (you can
do it quickly with Ctrl + a #) and then you can use Ctrl + r to get it back.
I'm sure there are other ways to save the command in the history but it is a
simple way to have the same effect.

~~~
reinhardt
I just put a random character instead of # to get "command not found".

~~~
sjs
# seems safer... what if you're typing a mv command on a BSD machine that also
has GNU binutils and the random character you hit is a "g"? Bad news.

------
gregable
Awk. Actually a full programming language but i usually use it for quick one
liners: [http://gregable.com/2010/09/why-you-should-know-just-
little-...](http://gregable.com/2010/09/why-you-should-know-just-little-
awk.html)

~~~
nikcub
every developer should know sed and awk. it is amazing how many devs write
cumbersome scripts or little programs to handle tasks that are built for sed
and awk.

my ~/bin folder has ~50 different little scripts that handle all sorts of
small tasks.

~~~
cop359
I don't really know a lot about this stuff, but my understanding is that Perl
was more or less replaced sed and awk.

~~~
caw
I code in Perl at my day job, and I still use awk and grep. Sometimes it's
quicker to do it in awk than perl, especially when you're doing it in command
line and have to figure out quotes.

awk -F, '{print $3}' foo | xargs -I{} echo 'command -x -y -z {}'

perl -e 'open F, "<foo"; while(<F>) { my($a,$b,$c,@rest) =split /,/;
system("command -x -y -z $c"); }'

I think I could do the split into an array and then take the third element,
but I'm just trying to do an elementary example. When you want to do more
things to this argument you necessarily have to grow this, and at one point I
got to the point where I started having to escape quotes. That's rather
difficult to read when you're just trying to do something quick in the command
line and you mismatch a pair.

~~~
ajays
Instead of opening the file "foo" by hand, you can use Perl's "awk mode"
thusly:

    
    
       perl -lane 'system("command -x -y -z $F[2]")' foo

------
sirn
For me, netcat. I mostly use it for

* Copying files across machines (`cat file| nc -l port` and `nc host port`)

* Remote pasteboard (on OSX w/ pbcopy, `while true; do nc -l port| pbcopy; done`)

Not a life changing, but I wish I know it earlier.

Only if there's a way to make "remote $EDITOR" with Netcat...

------
buster
Quitting SSH connections that hang: ~.

If you frequently connect through VPNs to other hosts, often enough the SSH
connection times out and just siits there, taking no commands. Hitting ~ and .
will kill the session (it's an openssh feature).

Other frequently used tools: awk, sort, uniq, tail, find, grep.. they alone
make the shell a really powerful tool

~~~
shabble
it's important to note that this needs to be preceeded by a newline to work.

so:

    
    
        <ret>~? (list possible escapes)
        <ret>~. (disconnect session)
    

If you're dumping binary data through ssh as a pipe, this can sometimes bite
you if these sequences appear in your data.

    
    
        ssh -oEscapeChar=none ...
    

handles that situation. (for the gory details, man ssh_config)

------
antimora
these are great ones!

But here is mine that I recently learned:

    
    
      sort -h 
    

compare human readable numbers (e.g., 2K 1G)

~~~
joelthelion
Canonical example:

    
    
        du -h | sort -h

~~~
caw
Sort to the same output file: sort -o foo.txt foo.txt

You can't do sort foo > foo because you'll be left with a blank file.

~~~
Karellen
sponge(1) from "moreutils"

Although sort(1) handles this for you as you mention, the general problem in
the shell of wanting to overwrite your input file with the output file, but
not being able to redirect to it for the reason you mention, is solved with
sponge. Rather than:

$ grep "foo" bar.txt >baz.txt; mv baz.txt bar.txt

instead:

$ grep "foo" bar.txt | sponge bar.txt

------
brown9-2
GNU Parallel: <http://www.gnu.org/s/parallel/>

------
Aissen
!$ (short for !!:$)

Passes last argument on the command line. In general, the whole paragraph on
HISTORY EXPANSION in the bash manual is a must read.

A few ones from the moreutils package:

\- vipe : manually edit the data in the middle of a pipe.

\- vidir : treat a directory and its files as a text file. Does renames and
deletions.

\- sponge : when you're doing modification on a file in a pipe, and want the
output to be to this file (file will be scrambled without sponge).

It has others, very useful tools, but I won't spoil them all.

~~~
sjs
alt-. or (ESC .) does something similar, but can be pressed repeatedly to keep
going back further in history in case the argument you want isn't on the most
recent command.

!! is short for the previous command, but you can do !-2$ to get the last
argument from the 2nd last command, or !cp$ to get the last argument from the
most recent cp command. Or !cp:2 to get the 2nd argument to the most recent cp
command. !# refers to the _current_ command being entered (in zsh, don't know
about bash).

Basically I second Aissen's recommendation to read up on history expansion.
Super useful.

------
helper
#proxy from port 80 to port 3001

socat TCP-LISTEN:80,fork TCP:localhost:3001

~~~
spudlyo
Great program, _socat_ is like netcat, but with a lot more features.

------
veyron
The way uniq should have been implemented:

    
    
        awk '!x[$1]++'

------
ethank
lsof comes in handy to match pid to socket and thus things like apache proc to
running MySQL process.

------
ryan-allen
strace - for looking a bit deeper into what's going on with live processes
when things go awry.

------
rhizome31
Most of those commands are not specific to GNU/Linux and will work with *BSD,
OS X, etc.

~~~
sjs
"Hey guys check out these sweet Ubuntu commands!" ;-)

------
wackfordjf3
In bash: cp /dir/dir/dir/dir/filename !#:^:h/newfilename (Applies to more than
cp) Strips cp & repeats previous dir tree minus /filename, plus /newfilename.

This can be mimicked by brace expansion: cp
/dir/dir/dir/dir/{filename,newfilename}

------
philjackson
The "^[." (esc-.) keybinding. In zsh it maps to insert-last-word which allows
you to do this:

    
    
        echo hi > /tmp/blah.txt
        ls -l <esc-.>
    

There's a bunch of complementary commands to go with it too.

~~~
sjs
Is this only in zsh? I've been recommending this and not marking it explicitly
as a zsh thing.

alt-. works too. In the shell ESC <foo> is the same as alt-<foo>. The
difference being that with alt-<foo> you hold alt and press <foo>, then
release them both. with ESC <foo> you press escape, release, and then press
and release <foo>.

~~~
philjackson
It's bash too.

------
djKianoosh
zless, zgrep, zcat... Only recently found out about these and now I love them

------
gbog
uptime. I had a phone screening itw with Google and it was the answer to one
question. I answered sar, which is much more powerful, and top, but caller
wasn't tech and I probably missed a checkbox.

~~~
wazoox
I always use "w" instead. It give the same information as uptime plus some
more (basically "who"), for much less typing.

------
phzbOx
For me, it was using 'cd' without argument. (It takes you back to your ~).
Also, learning the various options of grep (-v, -i, -A, -B) made its use
really more powerful.

~~~
redler
A useful one I somehow missed early on is

    
    
      cd -
    

to change back to whichever directory you were just in. Every once in a while
most of us find ourselves facing someone's "how could you not know that?"
look.

~~~
gnosis
Also along these lines are the directory stack manipulation commands: "pushd",
"popd", and "dirs" -- along with some related environment variables.

------
Tichy
I wonder, how do you remember all the command line options?

Recently I had this thought: maybe those people who can remember the options
actually are autistic (don't know the proper word, that thing many geeks are
deemed to be), and I am not. Remembering command line options might be like
knowing large prime numbers within seconds.

But I am also interested in memory techniques like the Loki method. Perhaps
some good system for memorizing command line arguments could be devised...

~~~
ilikejam
Umm, we just use the commands a lot. Doing something 12 hours a day for 10
years tends to leave some imprints on your memory.

------
samuel
set -o vi

------
1point2
The one that starts the system up - still forget what it is - but I know it
lives in /boot.

------
geekytenny
This is useful for finding and killing a process.

ps -A | grep _some text in program name_

upon getting the pid

kill -9 _pid_

~~~
telemachos
Instead of kill -9 (a nuke), you can often get results with just kill, kill
-INT or kill -HUP. (The advantage is that the "weaker" signals allow your
runaway program to do _some_ cleanup, but kill -9 doesn't.)

There's a nice write-up and a function automating attempts to run increasingly
strong signals on this site:
[http://web.archive.org/web/20080610070315/http://sial.org/ho...](http://web.archive.org/web/20080610070315/http://sial.org/howto/shell/kill-9/)

(Thank god for the wayback machine. That site was full of good Unix tips and
tutorials, but it's gone now.)

~~~
DaveChild
It's still there, just without a domain:

<http://72.14.189.113/>

~~~
telemachos
Thanks for letting me know. It's still probably easier to use the Wayback
Machine since all of the site's internal links point to <http://sial.org/> so
browsing within the site is very painful. Still, I'm glad to see the content
is all still online. I may just mirror the whole thing (there's tons of good
reference material in there, especially for Perl, but also for Unix
generally).

------
MPSimmons
I wish I would have known about dmidecode long before I found out about it.

~~~
gnosis
Along these lines there are also: lspci, lshw, and procinfo.

------
t_hozumi
du -sh ./D*

    
    
      872K	./Desktop
      78M	./Documents
      3.2G	./Downloads

~~~
k_bx
I would add | sort -h here

~~~
brendano
if you don't have "sort -h" (mine doesn't do it), you can also use "du -m",
which gives file sizes in megabytes -- pretty reasonable. (then "sort -n")

------
sarnowski
ctrl+d was an amazing improvement when my boss showed it to me years ago. Now
I discover that a lot of people don't know it.

~~~
roadnottaken
to logout or to delete characters?

~~~
snprbob86
More accurately: End Of File.

------
jasiek
pushd / popd

~~~
josch
also cd - which goes back to the last directory you cd'd from.

------
pvg
slabtop

~~~
gnosis
This looks interesting. But would it be useful to anyone who's not a kernel
developer?

------
jasiek
python -m json.tool < unformatted.json > formatted.json

edit: requires simplejson

------
Pelayo
screen

Saved my work on remote servers too many times to count. :)

------
yewtree
tree

------
Jim_Neath
mytop

------
cema
dd

------
1010010101
sed -n '/./{ /beg/,/end/p;}'

