1

There might be an easier way of doing this, I'm going to be running a bunch of commands on a box. I want to keep track of the successful ones so that I can make a script out of it to automate this in the future.

I tried

<command> && echo "!!" >> file

but the !! is printing the line before this one. I've tried a few other things but can't get something to work

8
  • Is there some reason why you can't just look at your history? As in run history.
    – Zoredache
    Dec 17, 2012 at 21:53
  • or use script...then remove the unsuccessfull commandes
    – Alex
    Dec 17, 2012 at 21:59
  • history stores all input, not just succesful commands (or even just exit status) Dec 17, 2012 at 21:59
  • @Zoredache Um, I guess but wont this include unsuccessful commands too? and how will I know where the history I want to repeat begins?
    – GP89
    Dec 17, 2012 at 21:59
  • 1
    Shouldn't you log the unsuccessful commands instead? Dec 17, 2012 at 21:59

3 Answers 3

3

You can do it like this:

PROMPT_COMMAND='[[ $? == 0 ]] && history 1 | sed -r "s/\ +[0-9]+\ +//" >> successful'

$PROMPT_COMMAND holds a command which bash executes before issuing a prompt. So what this does is evaluate the exit status of your previous command (after you press enter to execute your current command, but before bash evaluates it), and if it was successful, pull it from your bash history, strip the command number, and put add it to a separate file.

Now you don't have to tack on anything to your commands:

echo "exits successfully and will be appended"
ehco "only ends up in bash history"

Note that the readline history commands, !! and the rest of its family, only works in interactive shells, you cannot use those in scripts.

Also note that the -r option is gnu sed, bsd sed does not have it.

2
  • +1 this is awesome, although everything is getting appended, even the unsuccessful commands? That's fine I only plan to use the output in the successful file to make the script, so I wont be using !! for that.
    – GP89
    Dec 18, 2012 at 19:10
  • It helps if you test first :) Replace [[ $? ]] with [[ $? = 0 ]] to really make it only do succesful ones. Dec 18, 2012 at 19:10
1

I would use a second shell and strace. In shell 1, use echo $$ to find the PID of your shell. Then use strace -f -q -eexecve,exit_group -p that_pid_here to trace commands and exit statuses. The resulting output can then be mangled into a shellscript afterwards.

4
  • If I do this and try to use sudo in the other shell I get "sudo: must be setuid root". I'm starting to think this probably wasn't one of my best ideas.. lol
    – GP89
    Dec 17, 2012 at 22:08
  • 1
    try sudo strace and not strace sudo :) Dec 17, 2012 at 22:08
  • 1
    @DennisKaarsemaker the problem isn't sudo strace the problem is that once bash_shell_1 is being traced, setuid executables run inside that shell stop functioning right. See superuser.com/questions/247888/…
    – DerfK
    Dec 17, 2012 at 23:40
  • yea I didn't try to run strace with sudo, while its running it prevents me from using sudo in the second shell
    – GP89
    Dec 18, 2012 at 19:02
0

This will do - note it is ' instead of "

<command> && echo '!!' >> file
1
  • This echos the literal string !! into the file, rather than <command> or the command on the previous line like "!!" did.
    – GP89
    Dec 18, 2012 at 19:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .