A few weeks ago someone asked me to recommend a few useful books on Ruby. The first one? Using csh & tcsh. I spend a lot of time in the terminal and these shortcuts help in both tcsh and bash.
The ! operator gives you a quick way to refer to parts of the previous command.
How many times have you tried to edit a file, then realize that you need to be root to do it? Use bang-bang to quickly repeat the previous command, with other commands before or after.
emacs /etc/init.d/mongrel_cluster
=> Permission Denied
sudo !!
=> Now opens the file as root
Sometimes I need to reuse the last argument with another command, like here where I forgot to quote a string.
wget http://weather.yahooapis.com/forecastrss?p=98117
=> wget: No Match
wget '!$'
=> Now it works
I rarely use this, although it could have been used in the previous tip.
echo fish and chips
echo !^
=> fish # First argument
!:1 is the same as !^. The difference is that you can reference any element of the previous command.
echo fish and chips
=> fish and chips
echo !:1
=> fish # Same thing as !^
echo fish and chips
echo !:2
=> and # Word 2 in previous command, zero-indexed
echo fish and chips
echo !:0
=> echo # The very first word in the previous command
echo fish and chips
echo !:1-3
=> fish and chips # A range
The bang is useful for re-running a command that you’ve run before. Spell out the first few letters and hit ENTER (or TAB to show the completion in tcsh). The shell will search backwards in your history until it finds a command that starts with the same letters.
I like the tcsh behavior since you can hit TAB to see what you’re asking for. Using this in bash can be more adventurous since you don’t know what command will be run until you hit ENTER.
rake test:recent
...
!rak
=> Runs 'rake test:recent' or last command starting with 'rak'
How often do you rename just part of a file? The {} syntax is convenient.
mv file.{txt,xml}
=> Expands to 'mv file.txt file.xml'
mv file{,.orig}
=> Expands to 'mv file file.orig'
mkdir foo{1,2,3}
=> Expands to 'mkdir foo1 foo2 foo3'
In Mac OS X, you can copy things to the clipboard and read them back out. This is nice because you can reuse it in the shell or back in the OS with Apple-C or Apple-V.
./generate_random_password | pbcopy
pbpaste > file.txt
great Post! i didn’t know about some of these…
groovy man!
cheers
In bash, you can set up the magic space to show you what the ! commands will result in. To do this, add “Space: magic-space” to .inputrc.
So with !pattern, when you do
!rakand then hit space, it’ll be replaced withrake test:recent.I’ve been “getting around” to learning these for far too long. Thanks for the simple howto!
Fantastic! All of these were new for me.
I master these, thx
Most helpful, thanks Geoff. Now we even have ways of keeping the terminal DRY ;)
Great post, so many helpful hints, and somewhat freaky that I’m posting so close to jamie hill.
If you’re impressed by these somewhat basic tips, you are gonna love the zsh. Have a look at http://grml.org/zsh/ They have a great collection of zsh resources and tips.
Nice one Geoffrey.
bash also have some nice shortcuts…
insert last arg: alt + . (you can hold alt and press ”.” many times)
search backward: alt + r and start typing command (more informative then !pattern)
go to beginning/end of current string: ctrl+a, ctrl+e
erase word: ctrl+w
and many others…
One of my favorites is !#—this command.
So
cp foo !#^.bak
translates to
cp foo foo.bak
It’s great with very long file/pathnames.
One more trick with that: !#$ is “whatever I just said.”
echo abc def !#$.bak ghi jkl !#$.foo mno
is the same as
echo abc def def.bak ghi jkl jkl.foo mno
I’d be surprised if
worked very well.
shell metacharacters don’t interpolate inside single quotes.
One of my favourite uses of ”!!” is to test an expression before giving it to some destructive command. For example, check the list of files older than 120 days before deleting them:
Oops, there’s one file I don’t want to delete:
@robc: !$ is intepolated inside single quotes in my shell, but double will work, too (the example I gave was an actual command that I used a few minutes before writing this article).
Thanks to everyone for the other tips as well!
In the Beginning was the Command Line
Great post, It’s the first time I read about a ‘{}’ shell modifier :D
Cool Post, thanks a lot for it.
see you,
peter :-)
Wow. Thanks a million.
“Insa” mentioned: search backward: alt + r and start typing command (more informative then !pattern)
But in my experience it’s been Ctrl-r that searches backwards for patterns in your command history.
Another favorite is the use of caret(^) substitution, which you can use to fix a typo in the previous command. E.g.
great post. I’ll definitely use this stuff a lot, especially the {} trick.
@insa: good call on the ctrl+e. I have always used ctrl+a, but for some reason never knew how to get to the end of the line.
I like the {}! Nice
for any of the recall commands, :p will print it and put it into the most recent slot in the history, rather than execute it. this is useful when you’re searching for that last “rm” command:
dp 26% !rm:p rm /* dp 27%
there’s no evidence that the command didn’t execute, so this would show that:
dp 28% !ls:p ls / dp 29%
![n|string] is evaluates to all the arguments and options to the recalled command:
dp 34% touch /tmp/t1 /tmp/t2
dp 35% ls -l !* ls -l /tmp/t1 /tmp/t2
rw-r-r— 1 joel wheel 0 Jun 12 16:08 /tmp/t1rw-r-r— 1 joel wheel 0 Jun 12 16:08 /tmp/t2dp 36% rm !t* rm /tmp/t1 /tmp/t2
dp 37% ls !31* ls /tmp/t1 /tmp/t2 ls: /tmp/t1: No such file or directory ls: /tmp/t2: No such file or directory
Never seen any of them before, they’re gunna save some precious time for me! Just what I need as i just switched to linux to linux as my main OS (wish it was a mac though (yes, I admit it, only for textmate (and yes, i do like my brackets))). Cheers me dears.
Thanks for useful information. I really found Mac OS X specific very useful. The {} trick is cool
Yes, the {} is nice.
Thanks for cool post, Ed
thanks for these, they’re totally awesome! Is there any concise way to use the output of a previous command as the input to a new one? i.e. I did:
$ ls ~/Sites/grabbit/trunk/db/migrate/ | grep param
and the output was a single file. Now I want to open that file with textmate. I want something like:
$ mate [concise command]
Does that exist?