69 votes

Enregistrement du répertoire actuel dans l'historique bash

J'aimerais enregistrer le répertoire actuel dans lequel chaque commande a été émise à côté de la commande dans l'historique. Afin de ne pas gâcher les choses, je pensais ajouter le répertoire actuel sous forme de commentaire à la fin de la ligne. Un exemple pourrait aider:

 $ cd /usr/local/wherever
$ grep timmy accounts.txt
 

J'aimerais que bash sauvegarde la dernière commande en tant que:

 grep timmy accounts.txt # /usr/local/wherever
 

L'idée est que de cette façon je pourrais voir immédiatement où j'ai lancé la commande.

54voto

Dennis Williamson Points 105818

One-liner version

Voici un one-liner version. C'est l'original. J'ai aussi posté une fonction courte et une version longue de la fonction de la version avec plusieurs fonctionnalités ajoutées. J'aime la fonction des versions, parce qu'ils ne sont pas les fringues d'autres variables dans votre environnement et qu'elles sont beaucoup plus lisible que le one-liner. Ce post contient des informations sur la façon dont ils fonctionnent tous, qui ne peut pas être dupliqué dans les autres.

Ajoutez les lignes suivantes à votre ~/.bashrc le fichier:

export PROMPT_COMMAND='hpwd=$(history 1); hpwd="${hpwd# *[0-9]*  }"; if [[ ${hpwd%% *} == "cd" ]]; then cwd=$OLDPWD; else cwd=$PWD; fi; hpwd="${hpwd% ### *} ### $cwd"; history -s "$hpwd"'

Ce qui fait une entrée de l'historique qui ressemble à ceci:

rm subdir/file ### /some/dir

J'utilise ### comme un délimiteur de commentaire de chacun de commentaires que l'utilisateur peut entrer et de réduire le risque de collisions pour décaper la vieille chemin des commentaires qui seraient autrement s'accumuler si vous appuyez sur entrée sur une ligne de commande vide. Malheureusement, l'effet secondaire est que la commande echo " ### " obtient mutilé, bien que cela doit être assez rare.

Certaines personnes vont trouver le fait que je réutiliser le même nom de variable pour être désagréable. Normalement, je ne voudrais pas, mais ici, je suis en train d'essayer de minimiser l'empreinte. Il est facilement changé en tout cas.

Aveuglément suppose que vous ne l'utilisez pas HISTTIMEFORMAT ou de la modification de l'histoire d'une autre façon. Il serait facile d'ajouter un date commande pour le commentaire en lieu et place de l' HISTTIMEFORMAT fonctionnalité. Toutefois, si vous avez besoin de l'utiliser pour une raison quelconque, il travaille toujours dans un shell interne est exécuté car il peut annuler automatiquement:

$ htf="%Y-%m-%d %R "    # save it for re-use
$ (HISTTIMEFORMAT=$htf; history 20)|grep 11:25

Il ya un couple de très petits problèmes avec elle. L'une est que si vous utilisez l' history commande comme ceci, par exemple:

$ history 3
echo "hello world" ### /home/dennis
ls -l /tmp/file ### /home/dennis
history 3

Le résultat ne sera pas le commentaire sur l' history commande en elle-même, même si vous le verrez si vous appuyez sur flèche haut ou la question d'un autre history commande.

L'autre est que les commandes incorporées des retours à la ligne laisser une décommenté la copie dans l'histoire, en plus le commentaire de copie.

Il y a peut être d'autres problèmes qui se présentent. Laissez-moi savoir si vous en trouvez.

Comment ça marche

Bash exécute une commande contenue dans l' PROMPT_COMMAND variable à chaque fois que l' PS1 principal message est émis. Ce petit script prend avantage de cette pour attraper la dernière commande dans l'histoire, ajoutez un commentaire à lui et l'enregistrer en arrière.

Ici, il est divisé à part avec les commentaires:

hpwd=$(history 1)              # grab the most recent command
hpwd="${hpwd# *[0-9]*  }"      # strip off the history line number
if [[ ${hpwd%% *} == "cd" ]]   # if it's a cd command, we want the old directory
then                           #   so the comment matches other commands "where *were* you when this was done?"
    cwd=$OLDPWD
else
    cwd=$PWD
fi
hpwd="${hpwd% ### *} ### $cwd" # strip off the old ### comment if there was one so they 
                               #   don't accumulate, then build the comment
history -s "$hpwd"             # replace the most recent command with itself plus the comment

22voto

Dennis Williamson Points 105818

hcmnt au long de la fonction de la version

Voici une version longue sous la forme d'une fonction. C'est un monstre, mais il ajoute plusieurs fonctionnalités utiles. J'ai aussi posté un one-liner (l'original) et par une réduction de la fonction. J'aime la fonction des versions, parce qu'ils ne sont pas les fringues d'autres variables dans votre environnement et ils sont beaucoup plus lisible que le one-liner. Lire l'entrée pour le one-liner et le commments dans la fonction ci-dessous pour plus d'informations sur la façon dont il fonctionne et certaines limites. Je n'ai pas posté de chaque version dans sa propre réponse afin de garder les choses le plus organisé.

Pour l'utiliser, l'enregistrer dans un fichier appelé" hcmnt dans un endroit comme l' /usr/local/bin (vous pouvez en chmod +x , si vous le souhaitez) puis dans votre ~/.bashrc comme ceci:

source /usr/local/bin/hcmnt
export hcmntextra='date "+%Y%m%d %R"'
export PROMPT_COMMAND='hcmnt'

Ne pas modifier la fonction du fichier PROMPT_COMMAND ou hcmntextra sont définies. Les laisser comme ils restent comme valeurs par défaut. Les inclure dans votre .bashrc comme indiqué ci-dessus et de les modifier pour définir les options d' hcmnt ou pour modifier ou annuler hcmntextra. Contrairement à la fonction courte, avec celui-ci, vous devez tous les deux ont l' hcmntextra ensemble de variables et d' utiliser l' -e option pour faire de cette fonction de travail.

Vous pouvez ajouter plusieurs options qui sont documentés (avec un couple d'exemples) dans les commentaires dans la fonction. Une caractéristique remarquable est d'avoir de l'entrée de l'historique des annexes, des commentaires enregistrés sur un fichier et quitter la véritable histoire intacte. Pour utiliser cette fonction, ajouter l' -l nom de fichier option comme suit:

export PROMPT_COMMAND="hcmnt -l ~/histlog"

Vous pouvez utiliser n'importe quelle combinaison d'options, sauf qu' -n et -t sont mutuellement exclusifs.

#!/bin/bash
hcmnt() {

# adds comments to bash history entries (or logs them)

# by Dennis Williamson - 2009-06-05 - updated 2009-06-19
# http://stackoverflow.com/questions/945288/saving-current-directory-to-bash-history
# (thanks to Lajos Nagy for the idea)

# the comments can include the directory
# that was current when the command was issued
# plus optionally, the date or other information

# set the bash variable PROMPT_COMMAND to the name
# of this function and include these options:

    # -e - add the output of an extra command contained in the hcmntextra variable
    # -i - add ip address of terminal that you are logged in *from*
    #      if you're using screen, the screen number is shown
    #      if you're directly logged in, the tty number or X display number is shown
    # -l - log the entry rather than replacing it in the history
    # -n - don't add the directory
    # -t - add the from and to directories for cd commands
    # -y - add the terminal device (tty)
    # text or a variable

# Example result for PROMPT_COMMAND='hcmnt -et $LOGNAME'
#     when hcmntextra='date "+%Y%m%d %R"'
# cd /usr/bin ### mike 20090605 14:34 /home/mike -> /usr/bin

# Example for PROMPT_COMMAND='hcmnt'
# cd /usr/bin ### /home/mike

# Example for detailed logging:
#     when hcmntextra='date "+%Y%m%d %R"'
#     and PROMPT_COMMAND='hcmnt -eityl ~/.hcmnt.log $LOGNAME@$HOSTNAME'
#     $ tail -1 ~/.hcmnt.log
#     cd /var/log ### dave@hammerhead /dev/pts/3 192.168.1.1 20090617 16:12 /etc -> /var/log


# INSTALLATION: source this file in your .bashrc

    # will not work if HISTTIMEFORMAT is used - use hcmntextra instead
    export HISTTIMEFORMAT=

    # HISTTIMEFORMAT still works in a subshell, however, since it gets unset automatically:

    #   $ htf="%Y-%m-%d %R "    # save it for re-use
    #   $ (HISTTIMEFORMAT=$htf; history 20)|grep 11:25

    local script=$FUNCNAME

    local hcmnt=
    local cwd=
    local extra=
    local text=
    local logfile=

    local options=":eil:nty"
    local option=
    OPTIND=1
    local usage="Usage: $script [-e] [-i] [-l logfile] [-n|-t] [-y] [text]"

    local newline=$'\n' # used in workaround for bash history newline bug
    local histline=     # used in workaround for bash history newline bug

    local ExtraOpt=
    local LogOpt=
    local NoneOpt=
    local ToOpt=
    local tty=
    local ip=

    # *** process options to set flags ***

    while getopts $options option
    do
        case $option in
            e ) ExtraOpt=1;;        # include hcmntextra
            i ) ip="$(who --ips -m)" # include the terminal's ip address
                ip=($ip)
                ip="${ip[4]}"
                if [[ -z $ip ]]
                then
                    ip=$(tty)
                fi;;
            l ) LogOpt=1            # log the entry
                logfile=$OPTARG;;
            n ) if [[ $ToOpt ]]
                then
                    echo "$script: can't include both -n and -t."
                    echo $usage
                    return 1
                else
                    NoneOpt=1       # don't include path
                fi;;
            t ) if [[ $NoneOpt ]]
                then
                    echo "$script: can't include both -n and -t."
                    echo $usage
                    return 1
                else
                    ToOpt=1         # cd shows "from -> to"
                fi;;
            y ) tty=$(tty);;
            : ) echo "$script: missing filename: -$OPTARG."
                echo $usage
                return 1;;
            * ) echo "$script: invalid option: -$OPTARG."
                echo $usage
                return 1;;
        esac
    done

    text=($@)                       # arguments after the options are saved to add to the comment
    text="${text[*]:$OPTIND - 1:${#text[*]}}"

    # *** process the history entry ***

    hcmnt=$(history 1)              # grab the most recent command

    # save history line number for workaround for bash history newline bug
    histline="${hcmnt%  *}"

    hcmnt="${hcmnt# *[0-9]*  }"     # strip off the history line number

    if [[ -z $NoneOpt ]]            # are we adding the directory?
    then
        if [[ ${hcmnt%% *} == "cd" ]]    # if it's a cd command, we want the old directory
        then                             #   so the comment matches other commands "where *were* you when this was done?"
            if [[ $ToOpt ]]
            then
                cwd="$OLDPWD -> $PWD"    # show "from -> to" for cd
            else
                cwd=$OLDPWD              # just show "from"
            fi
        else
            cwd=$PWD                     # it's not a cd, so just show where we are
        fi
    fi

    if [[ $ExtraOpt && $hcmntextra ]]    # do we want a little something extra?
    then
        extra=$(eval "$hcmntextra")
    fi

    # strip off the old ### comment if there was one so they don't accumulate
    # then build the string (if text or extra aren't empty, add them plus a space)
    hcmnt="${hcmnt% ### *} ### ${text:+$text }${tty:+$tty }${ip:+$ip }${extra:+$extra }$cwd"

    if [[ $LogOpt ]]
    then
        # save the entry in a logfile
        echo "$hcmnt" >> $logfile || echo "$script: file error." ; return 1
    else

        # workaround for bash history newline bug
        if [[ $hcmnt != ${hcmnt/$newline/} ]] # if there a newline in the command
        then
            history -d $histline # then delete the current command so it's not duplicated
        fi

        # replace the history entry
        history -s "$hcmnt"
    fi

} # END FUNCTION hcmnt

# set a default (must use -e option to include it)
export hcmntextra='date "+%Y%m%d %R"'      # you must be really careful to get the quoting right

# start using it
export PROMPT_COMMAND='hcmnt'

mise à jour 2009-06-19: Ajout d'options utiles pour la connexion (ip et ats), une solution de contournement pour l'entrée en double problème, retiré étrangères null affectations

7voto

Dennis Williamson Points 105818

hcmnts - court en fonction de la version

Voici une version abrégée sous la forme d'une fonction. J'ai aussi posté un one-liner (l'original) et une plus fonctionner avec plusieurs fonctionnalités ajoutées. J'aime la fonction des versions, parce qu'ils ne sont pas les fringues d'autres variables dans votre environnement et qu'elles sont beaucoup plus lisible que le one-liner. Lire l'entrée pour le one-liner pour plus d'informations sur la façon dont cela fonctionne, et certaines limitations. Je n'ai pas posté de chaque version dans sa propre réponse afin de garder les choses le plus organisé.

Pour l'utiliser, l'enregistrer dans un fichier appelé" hcmnts dans un endroit comme l' /usr/local/bin (vous pouvez en chmod +x , si vous le souhaitez) puis dans votre ~/.bashrc comme ceci:

source /usr/local/bin/hcmnts

Commentaire la ligne qui définit hcmntextra si vous ne voulez pas la date et l'heure (ou vous pouvez modifier le format ou l'utilisation d'une autre commande en plus de date).

C'est tout là est à lui.

#!/bin/bash
hcmnts() {
    # adds comments to bash history entries

    # the *S*hort version of hcmnt (which has many more features)

    # by Dennis Williamson
    # http://stackoverflow.com/questions/945288/saving-current-directory-to-bash-history
    # (thanks to Lajos Nagy for the idea)

    # INSTALLATION: source this file in your .bashrc

    # will not work if HISTTIMEFORMAT is used - use hcmntextra instead
    export HISTTIMEFORMAT=

    # HISTTIMEFORMAT still works in a subshell, however, since it gets unset automatically:

    #   $ htf="%Y-%m-%d %R "    # save it for re-use
    #   $ (HISTTIMEFORMAT=$htf; history 20)|grep 11:25

    local hcmnt
    local cwd
    local extra

    hcmnt=$(history 1)
    hcmnt="${hcmnt# *[0-9]*  }"

    if [[ ${hcmnt%% *} == "cd" ]]
    then
        cwd=$OLDPWD
    else
        cwd=$PWD
    fi

    extra=$(eval "$hcmntextra")

    hcmnt="${hcmnt% ### *}"
    hcmnt="$hcmnt ### ${extra:+$extra }$cwd"

    history -s "$hcmnt"
}
export hcmntextra='date +"%Y%m%d %R"'
export PROMPT_COMMAND='hcmnts'

1voto

Riaan Points 34

Gentleman cela fonctionne mieux.. La seule chose que je n'arrive pas à comprendre est comment faire le script n'est PAS connecter à un serveur syslog sur login et journal de la dernière commande dans l'histoire. Mais fonctionne comme un charme jusqu'à présent.

#!/bin/bash

trackerbash() {
 # ajoute des commentaires pour les entrées de l'historique de bash

 # par Dennis Williamson
 # http://stackoverflow.com/questions/945288/saving-current-directory-to-bash-history
 # (merci à Lajos Nagy pour l'idée)

 #Souper Renforcée par QXT


 # INSTALLATION: source de ce fichier dans votre dossier .bashrc

 l'exportation HISTTIMEFORMAT=
# export HISTTIMEFORMAT='%F %T '

 local hcmnt
 local cwd
 local supplémentaire
 local thistty
 local whoiam
 local sudouser
 local shelldate
 local TRACKIP
 local TRACKHOST


 thistty=`/usr/bin/ats|/bin/cut-f3-4 -d/`
whoiam=`/usr/bin/whoami`
 sudouser= " last |grep $thistty |head -1 | awk '{ print $1 }' |cut-c 1-10`
 hcmnt=$(histoire 1)
 hcmnt="${hcmnt# *[0-9]* }"
la mdc=`pwd`



 hcmnt="${hcmnt% ### *}"
 hcmnt=" $hcmnt ${supplémentaire:+$extra }"

 shelldate=`date +"%A %b %d %R:%S"`
 TRACKHOST=`whoami | sed -r "s/.*\((.*)\).*/\\1/"`
 TRACKIP= " last |grep $thistty |head -1 | awk '{ print $3 }"


 logger-p local1.avis -t bashtracker -i -- "$sudouser ${UTILISATEUR}: $thistty: $TRACKIP: $shelldate: $cwd : $hcmnt"
 histoire -w 

}
l'exportation PROMPT_COMMAND='trackerbash'

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X