Run last command as root(blog.hardikr.com)
blog.hardikr.com
Run last command as root
http://blog.hardikr.com/post/2337320222/sudo-previous-command
15 comments
Hi HN! I'm the post author, and if I would've known someone was submitting this to HN, I would've researched a bit more! This was more for my reference. Thanks for all the tips though, got to learn a lot from this thread..
Something else really useful:
mkdir stuff
cd !$
!$ takes the last argument from the previous command, instead of the whole thing.
chmod 664 site/* - changes the permissions for all the files in the site directory. * is a wildcard in bash for specifying directories.
Another useful feature of bash is brace expansion: mv site{,-old} => mv site site-old The brace expansion expands the argument with the values in a comma separated list: college pic_00{1,4,3}.jpeg college.jpeg yields pic_001 pic_004, pic_003
!$ takes the last argument from the previous command, instead of the whole thing.
chmod 664 site/* - changes the permissions for all the files in the site directory. * is a wildcard in bash for specifying directories.
Another useful feature of bash is brace expansion: mv site{,-old} => mv site site-old The brace expansion expands the argument with the values in a comma separated list: college pic_00{1,4,3}.jpeg college.jpeg yields pic_001 pic_004, pic_003
* is a wildcard in general. Its behavior is identical to the .* in a regular expression.
I have a function for it which is quite useful:
mcd () {
mkdir "$@"
cd "$@"
}
Just run mcd foobar and you (try) to create the directory and enter it. IMO a nice shortcut.
Just run mcd foobar and you (try) to create the directory and enter it. IMO a nice shortcut.
You know that mkdir can take multiple directories? If you run:
mcd dir1 dir2 dir3
That function will run: mkdir "dir1" "dir2" "dir3" cd "dir1" "dir2" "dir3"
(Surrounding $@ with double quotes, puts quotes around each item instead of quotes around the whole string: command "directory1/sub directory" "directory2"
$@ => directory1/sub directory directory2
"$@" => "directory1/sub directory" "directory2"
"$*" => "directory1/sub directory directory2"
)The biggest shell-related revelation for me recently was that ~ is a special character in SSH. If you have an SSH session that's hanging and ctrl-C / ctrl-D isn't responding, try typing "~." (without the quotes).
man ssh | grep -A 30 tildeThe ~ needs to follow a newline. So I usually make sure to hit <Enter> explicitly before hitting "~." so that I don't have to repeat the sequence if it doesn't work. It would still work without hitting <Enter> explicitly if the last thing that you typed to the console was <Enter> though.
If you have an SSH session that's hanging
It's usually because I've accidentally fumbled ctrl-s which means 'play dead'. Why that's important enough to take a two-key home row shortcut, I don't know. The cure is to press ctrl-q. Same wonder about the cure.
It's usually because I've accidentally fumbled ctrl-s which means 'play dead'. Why that's important enough to take a two-key home row shortcut, I don't know. The cure is to press ctrl-q. Same wonder about the cure.
I can't argue for it taking such a prime spot on the keyboard, but I used c-s/c-q every day to freeze scrolling output that I want to look at. Your terminal scrollback will still work during the pause.
I've always pronounced this command as
"sudo make me a sandwich"
"sudo make me a sandwich"
Seriously, though, "!!" is just a special case of Bash's history expansion
man bash, and search for "^HISTORY EXPANSION" for all the details.
I often find myself running commands like
cp !:2 !:1 # reverses the order of the last two args
cd /somedir && !! # run the last command in a better directory
man bash, and search for "^HISTORY EXPANSION" for all the details.
I often find myself running commands like
cp !:2 !:1 # reverses the order of the last two args
cd /somedir && !! # run the last command in a better directory
I prefer Ctrl-P, Ctrl-A, "sudo ", enter
It's pretty much the same number of keystrokes aside from having to hold down the Ctrl key. However, I can now go back in my history and run the command again. Also, if I mistyped something, I can easily hit Ctrl-P and fix it without having to retype sudo.
It's pretty much the same number of keystrokes aside from having to hold down the Ctrl key. However, I can now go back in my history and run the command again. Also, if I mistyped something, I can easily hit Ctrl-P and fix it without having to retype sudo.
!! (bang-bang) is expanded by the shell before its committed to your history (at least in bash), so if you hit ctrl+p, you'll get the full sudo command for running/modifying later.
In zsh, !! is expanded by the shell, but leaves the expanded command at the terminal, waiting for you to execute it. Most of the time this means I have to hit enter twice to run the command, but it's convenient when I want to explain to someone what !! is useful for.
I don't have that enabled but zsh also expands bang constructs with tab. So any commands I want to double check, or if I am demonstrating to someone, I just hit tab. Also handy for expressions like !-2:3 where if I messed up I can just hit "undo" and then retry.
Ah. Good to know.
Similarly, I always rehearse dangerous removals with ls :
ls ./t*
# looks good...
rm !$On a related note, when you want to insert something at the start of a line in a shell, rather than hitting home, I find ctrl-a to be very useful. Especially on a macbook, where cmd-left doesn't work in a shell (for some reason) and there is no home key.
This often works in unexpected places. For example: testing it right now, I can click the address bar on google chrome, hit ctrl-a (not cmd-a) and the caret is at the start of the url.
This often works in unexpected places. For example: testing it right now, I can click the address bar on google chrome, hit ctrl-a (not cmd-a) and the caret is at the start of the url.
Thanks (to jrockway too), that's something new I learned today!
ctrl-a (beginning of line), ctrl-e (end of line), ctrl-k (kill/copy line), ctrl-y (yank/paste line) are standard emacs keybindings. On OS X, they work in any standard NS text field as well. More at http://www.hcs.harvard.edu/~jrus/site/cocoa-text.html
BTW, when using screen, ctrl-a is its default action key, so use ctrl-a ctrl-a to send a real ctrl-a, or change the default screen action key in your .screenrc.
BTW, when using screen, ctrl-a is its default action key, so use ctrl-a ctrl-a to send a real ctrl-a, or change the default screen action key in your .screenrc.
> BTW, when using screen, ctrl-a is its default action key
This ends up annoying me on a regular basis. Let's say I want to make a directory and then go to it. I would type:
This ends up annoying me on a regular basis. Let's say I want to make a directory and then go to it. I would type:
mkdir foo<Ctrl-p><Ctrl-a><Alt-d>cd<Enter>
Except when using screen, <Ctrl-a><Alt-d> (really just <Ctrl-a>d) detaches the session. It's solved easily enough ("screen -r"), but it always yanks me out of my groove.Put something like this in your .screenrc:
This is the same as:
escape "^^^^"
That will set the escape character to ctrl-carat instead of ctrl-a. To type a literal ctrl-carat, type it twice.This is the same as:
screen -e ^^^^I prefer to bind it to ` with `` to send a real `. It makes it really easy to flip back and forth between two screen windows since last-window is now:
I do have bindings on F11 and F12 to toggle the escape character between ` and C-o. (Just in case I need to paste something into a terminal with ` characters.)
(Note: This whole setup is ripped off from some StackOverflow or HN post.)
`q
Now I don't even have to use Ctrl. This takes a little getting used to, but I prefer to use $() instead of `` for shell scripts (I use bash/zsh) so I don't make use of ` that often.I do have bindings on F11 and F12 to toggle the escape character between ` and C-o. (Just in case I need to paste something into a terminal with ` characters.)
(Note: This whole setup is ripped off from some StackOverflow or HN post.)
Ctrl-a ctrl-a toggles between screens; ctrl-a a sends a ctrl-a sequence to the terminal.
Another one to add to the list, when working in the shell, is ctrl-u. This sort of does the opposite of ctrl-k and clears everything from your cursor to the start of the line. I use it when I recursive-search then change my mind, or when I screw up a password when ssh'ing.
It's my understanding that these keycombo's are originally from the readline library. Other programs that have these combo's available are irrsi and bash but I love to know more!
[deleted]
Your MacBook does have a home key, it's just not labelled any more. fn+left arrow is home, and end is the obvious counterpart. fn+up/down are page up/down too.
I use ctrl-a and ctrl-e too, but sometimes you're using remote desktop (or synergy) with a Windows machine...
I use ctrl-a and ctrl-e too, but sometimes you're using remote desktop (or synergy) with a Windows machine...
One of my favorite, under-known Bash tricks: Ctrl-O. "Enter current command, put next history item on command line."
It works like this: You're doing 3 things over and over again, but you need to see each step finished before you want to go on. Something like:
>wget buildserver/artifact.jar >java -j artifact.jar > result.txt >grep "Stupid bug" result.txt >vi config.xml >git commit -a; git push
Something like that. Having done it once, up-arrow into your history to the wget, hit "Ctrl-O" and it'll execute the wget, and now the java command is ready. You can just keep cycling through with Ctrl-O, since executing the command puts it in the end of your history. If you need to update the command, the fix is available for later. One of those "use it so that you remember, 'cause boy-howdy it's handy"
It works like this: You're doing 3 things over and over again, but you need to see each step finished before you want to go on. Something like:
>wget buildserver/artifact.jar >java -j artifact.jar > result.txt >grep "Stupid bug" result.txt >vi config.xml >git commit -a; git push
Something like that. Having done it once, up-arrow into your history to the wget, hit "Ctrl-O" and it'll execute the wget, and now the java command is ready. You can just keep cycling through with Ctrl-O, since executing the command puts it in the end of your history. If you need to update the command, the fix is available for later. One of those "use it so that you remember, 'cause boy-howdy it's handy"
Have a look at zsh, you can execute your current command as root quite easy. Put
For more cool stuff regarding zsh have a look at http://grml.org/zsh/ or for other nice keybindings http://grml.org/zsh/grmlzshrc.html
sudo-command-line() {
[[ -z $BUFFER ]] && zle up-history
[[ $BUFFER != sudo\ * ]] && BUFFER="sudo $BUFFER"
}
zle -N sudo-command-line
bindkey "^Os" sudo-command-line
into your zshrc, enter the command and press ctrl+o s et voila ;0For more cool stuff regarding zsh have a look at http://grml.org/zsh/ or for other nice keybindings http://grml.org/zsh/grmlzshrc.html
zle = zsh line editor
(I doesn't use read-line it has it's own line editor)
(I doesn't use read-line it has it's own line editor)
I never do this, I prefer to recall the actual command to see if it is correct, especially for sudo.
The reason is that you might not execute the command you were thinking of. The HISTIGNORE variable contains a quasi-regex of commands that are not stored in history. If the previous command matched that regex, you will end up executing the previous command to that one, not what you wanted at all.
Why use HISTIGNORE?. So that things like 'exit' or common commands like 'ls' don't pollute your history file.
The reason is that you might not execute the command you were thinking of. The HISTIGNORE variable contains a quasi-regex of commands that are not stored in history. If the previous command matched that regex, you will end up executing the previous command to that one, not what you wanted at all.
Why use HISTIGNORE?. So that things like 'exit' or common commands like 'ls' don't pollute your history file.
I've really enjoyed Ctrl+a and Ctrl+e recently to move between the beginning and end of the command prompt - it's really a lot more useful than I initially thought.
I am just curious, what determines the front page of Hacker News? Because this post has 17 points and the one below it has 130 at this time
From what I've seen (and I may be wrong here), I think the post that enters the front page stays on the top just for a short amount of time, before gradually settling down on a position determined by the time it's been there, the votes it's got and flags. The post will keep sliding down with time.
Edited: Clarifying.
It is function of time, votes, and flags.
I can't find the post but it is essentially:
Ranking = (votes)^(1/time) with some other bells an whistles.
Ranking = (votes)^(1/time) with some other bells an whistles.
Here's an excellent, detailed, and fairly recent explanation of the Hacker News ranking algorithm:
http://amix.dk/blog/post/19574
http://amix.dk/blog/post/19574
sudo !!
runs the previous line as root, in case you forgot to type sudo
More like "sudo !!" prepends sudo to the last history entry and executes the result. It may not run as root, depending on the complexity of the shell handiwork you did, and depending on /etc/sudoers.
I really, really, really hope that the author doesn't think "sudo !!" is some special kind of magic, and that he knows "echo !!" works the same way.
Also, there are keyboards with a "Home" key? Most people just press C-a.
I really, really, really hope that the author doesn't think "sudo !!" is some special kind of magic, and that he knows "echo !!" works the same way.
Also, there are keyboards with a "Home" key? Most people just press C-a.
Do you know where I can find a list of hotkeys along the lines of C-a? I personally created my own hotkey (shift left arrow) but learning standard ones would probably be good.
Most shells default to emacs keybindings:
In zsh I actually have M-w bound to the normal backspace-by-a-word and C-w bound to the vim version which will do things like count '/' as a word separator so that I can easily backspace through sections of a path rather than be required to delete the whole thing (or nothing).
C-a beginning of line
C-k kill text from cursor to end of line
C-e end of line
M-b move cursor backwards by a word
M-f move cursor forwards by a word
C-w delete backwards by a word
C-h backspace (great when real backspace doesn't work)
C-r reverse search through command history
(C-w works in Vim(insert mode) and Emacs, but kills me when I try to type it in a browser window to delete a word... Good-bye window and/or tab)In zsh I actually have M-w bound to the normal backspace-by-a-word and C-w bound to the vim version which will do things like count '/' as a word separator so that I can easily backspace through sections of a path rather than be required to delete the whole thing (or nothing).
> (C-w works in Vim(insert mode) and Emacs, but kills me when I try to type it in a browser window to delete a word... Good-bye window and/or tab)
Control-Shift-T usually solves that problem for me in Firefox.
Control-Shift-T usually solves that problem for me in Firefox.
Hmm, FYI most of those work in the safari reply box. I think Apple put them for all Cocoa text fields not just terminal :-)
> I think Apple put them for all Cocoa text fields not just terminal :-)
It is the NSTextField that accepts those commands. The prefix NS stands for NeXTSTEP, so the functionality existed long before Cocoa.
It is the NSTextField that accepts those commands. The prefix NS stands for NeXTSTEP, so the functionality existed long before Cocoa.
Yea, but you have to hit Ctrl+Option or Cmd+Option (can't remember which off the top of my head) for Meta though, instead of just Option (which is what most people bind to Meta in Terminal.app or iTerm.app).
If you use bash, read the "Command Line Editing" section of "info readline".
You can also tweak the behavior of readline (for Bash and other applications) and custom make your own key combinations by editing your ~/.inputrc file. A random example from mine:
http://www.gnu.org/software/bash/manual/bashref.html#Command...
# Insert double quotes & set cursor between them
"\C-x\"": "\"\"\eb"
#
# Insert single quotes & set cursor between them
"\C-x'": "''\eb"
See also the Bash manual:http://www.gnu.org/software/bash/manual/bashref.html#Command...
Yeah, I first tried...
grep ".jpg"
^C
ls | !!
...that worked too. Cool command to learn.
Thanks for the clarification, though. Original article was lacking.
grep ".jpg"
^C
ls | !!
...that worked too. Cool command to learn.
Thanks for the clarification, though. Original article was lacking.
Hi, I'm the author (admittedly still quite new to Unix). I did play around with the !! and realized it does a lot more. Thanks for clarifying though!
Edit: Typos
Edit: Typos
It's very powerful. There's more than just the !! for history, also. Check out http://www.catonmat.net/blog/the-definitive-guide-to-bash-co... .
[deleted](1)