2

Given that I have the following alias in one of my bash initialization files (.bash_profile etc.):

alias gs='git status'

How can I get my .bash_history file to show the replacement text: 'git status' instead of the alias: 'gs'?

  • It seems to me that seeing the 'real' command that was executed would be the only way to make the history file meaningful to others who don't know my aliases. Hope this helps clarify the intent behind my question. – webappzero Dec 9 '14 at 20:26
0

I don't think that this is (easily) possible.

I tried this:

alias foo="echo foo;fc -e /home/hl/tmp/testscript.sh 0"
start cmd:> cat /home/hl/tmp/testscript.sh
#! /bin/bash

set -x

# simple case
#test -f "$1" || exit 1
#echo ": alias replacement : echo foo" >"$1"


# complex case
IFS= read -r line <"$1"
: line: _"$line"_
case "$line" in
        foo)
                echo ": alias replacement : echo foo" >"$1"
        ;;
        bar)
                echo ": alias replacement : echo bar" >"$1"
        ;;
        *)
                echo ": alias replacement error" >"$1"
        ;;
esac

The idea was: Run the actual command and immediately afterwards correct the command history which can be done by the bash builtin fc. There are two problems:

  1. fc allows you to edit the file but executes it afterwards. This can partly be solved by writing a dummy command (e.g. prepend :).

  2. The history is based on lines not on executed commands. Thus the command to be modified is not even on the stack yet. This could maybe be addressed by some evil hack like putting the code into $PS1 but I don't feel like trying...

history builtin

There may be a better way which shares the "not yet on the stack" problem with the above approach. I wasn't aware of the builtin history. This command allows to write and read the history file. Thus this could be done:

  1. write the file
  2. modify the file with e.g. sed: sed -i 's/^gs$/git status/' ~/.bash_history
  3. read the file

The history stack problem may be adressed this way (I didn't try, though):

alias foo="echo foo;(sleep 1; history ...) &"
  • Thanks for you thought provoking answer. I did find that adding shopt -s cmdhist to any bash initialization file (.bash_profile etc.) will instruct bash to accept entire multiline commands as a single entry in the history list. – webappzero Dec 10 '14 at 15:18
  • You can check to see if cmdhist is on already by running just: shopt – webappzero Dec 10 '14 at 15:23
  • @webapphero But this isn't multiline problem, is it? I had a look at the man page because I am not familiar with cmdhist and I noticed the builtin history. I extended my answer. – Hauke Laging Dec 10 '14 at 15:45
  • 1
    How about a variation of unix.stackexchange.com/a/158697/70524, but with replacing foo with ${BASH_ALIASES[foo]}? – muru Dec 10 '14 at 16:38
  • @HaukeLaging no it isn't a multiline problem in itself. I was simply addressing a portion of your answer in which you stated that bash worked off of individual lines, in hopes that it would be helpful. – webappzero Dec 10 '14 at 17:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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