Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

When I am running my analyses using the bash shell, I often want to save the commands I've used that gave me good results to a file in the same directory (my "LOGBOOK", as its called) so that I can check what I did to get those results. So far this has meant me either copy.pasting the command from the terminal or pressing "up" modifying the command to an echo"my command" >> LOGBOOK, or other similar antics.

I found there was a history tool the other day, but I can't find a way of using it to get the previously executed command so that I can do something like getlast >> LOGBOOK.

Is there a nice easy way to do this. Alternatively, how do others deal with saving the commands for results they have?

share|improve this question

5 Answers 5

up vote 9 down vote accepted

If you are using bash, you can use the fc command to display your history in the way you want:

fc -ln -1

That will print out your last command. -l means list, -n means not to prefix lines with command numbers and -1 says to show just the last command. If the whitespace at the start of the line (only the first line on multi-line commands) is bothersome, you can get rid of that easily enough with sed. Make that into a shell function, and you have a solution as requested (getlast >> LOGBOOK):

getlast() {
    fc -ln "$1" "$1" | sed '1s/^[[:space:]]*//'
}

That should function as you have asked in your question.

I have added a slight variation by adding "$1" "$1" to the fc command. This will allow you to say, for example, getlast mycommand to print out the last command line invoking mycommand, so if you forgot to save before running another command, you can still easily save the last instance of a command. If you do not pass an argument to getlast (i.e. invoke fc as fc -ln "" "", it prints out just the last command only).

[Note: Answer edited to account for @Bram's comment and the issue mentioned in @glenn jackman's answer.]

share|improve this answer
3  
The first form fc -lnr | head -n 1 can be abbreviated to fc -lnr -1. –  Bram May 7 '12 at 11:45
    
@Bram: Good stuff. I was using help fc for my documentation. The bash man page has more details, including this use of negative indices. Eliminating head is good because the one command left is built-in so now there's no fork/exec. –  camh May 7 '12 at 11:59
    
I wonder why the command is called fc... –  imz -- Ivan Zakharyaschev May 7 '12 at 21:46
1  
It stands for "fix command". gnu.org/software/bash/manual/bashref.html#Bash-History-Builtins –  Mikel May 8 '12 at 1:15

One problem with @camh's answer is if you have a command that spans multiple lines, it only shows the first line:

$ echo "one
> two
> three"
one
two
three

$ fc -lnr | head -1
         echo "one

Try this:

$ alias getlast='fc -nl $((HISTCMD - 1))'

$ echo "one
> two
> three"
one
two
three

$ getlast
         echo "one
two
three"
share|improve this answer
3  
enabling cmdhist will fix that: "If set, bash attempts to save all lines of a multiple-line command in the same history entry. This allows easy re-editing of multi-line commands." –  mmckinst May 7 '12 at 21:17

You can do that with the following command if you are using bash shell:

$> history -a LOGBOOK

This will append all your commands from current session to that file, you can also add an alias on your ~/.bashrc file to do this with a single command:

$> alias getlast="history -a LOGBOOK"
share|improve this answer
    
But you're missing the more important requirement that I only save the commands that worked and got the results I have. I don't want to save all the recent commands I've done, just select ones after I've used them. Thanks anyway. –  kikumbob May 7 '12 at 10:27

Instead of using the up arrow, you can use "!!" to refer to the previous command.

e.g.

$ some -long --command --difficulty="very hard to remember"
$ echo "!!" >> LOGBOOK

note: this does not quote the literal text

share|improve this answer
    
That will not capture the literal command. If there are any shell metacharacters, they will be evaluated and substituted. Pipelines will also break: ls | less -> echo !! >> LOGBOOK -> echo ls | less >> LOGBOOK. –  camh May 8 '12 at 1:04

This works for me:

echo -e !! >> file.txt

file.txt should now contain your last command.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.