File log riwayat bash / zsh per-direktori

14

Saya menemukan saya melakukan banyak pekerjaan pada proyek di direktori set. Kadang-kadang - beberapa bulan ke belakang - saya perlu mengulang sesuatu pada proyek itu tetapi saya tidak ingat apa yang saya lakukan. Saya menggunakan mercurial atau git untuk melacak perubahan pada file tetapi saya ingin dapat mengingat perintah apa yang saya keluarkan di direktori itu.

Mencari melalui riwayat shell saya tidak terlalu informatif. Saya sudah mencatat semuanya ke file. * _ History saya, tetapi saya ingin daftar hal-hal yang saya lakukan di ~ / foo / bar, dan tidak semua (juta) hal lain yang saya lakukan minggu itu. Saya mungkin bahkan tidak ingat bulan terakhir saya mengerjakan proyek itu.

Apakah ada yang punya ide bagaimana file log direktori proyek dari semua perintah shell yang saya gunakan? Saya membayangkan sesuatu perintah seperti:

workon myproject

... yang akan mengatur file log shell ke ~ / myproject / .history.log, muat riwayat sebelumnya dari logfile itu, dan mungkin perbarui prompt saya untuk memberi tahu saya direktori apa yang sedang saya kerjakan (seperti misalnya vcprompt untuk menyediakan versi info kontrol).

Apakah ada yang seperti ini di luar sana?

Simon
sumber

Jawaban:

4

Jika Anda belum mengetahuinya: apa yang Anda cari adalah paket virtualenvwrapper yang sangat baik . Ini adalah pembungkus di sekitar virtualenv python (angka go) dan, sementara itu umumnya disebut ketika mengambil tentang lingkungan python, itu sebenarnya adalah alat yang sangat umum yang memenuhi kasus penggunaan Anda.

Instalasi

pip install virtualenvwrapper

atau

easy_install virtualenvwrapper

dan menambahkan hal-hal inisialisasi ke konfigurasi shell Anda ( ~/.zshrc, ~/.bashrc)

export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$WORKON_HOME/projects
export PIP_VIRTUALENV_BASE=$WORKON_HOME
export PIP_RESPECT_VIRTUALENV=true
source /usr/local/bin/virtualenvwrapper.sh

Pemakaian

# create your env
mkvirtualenv my_project

# edit per project hooks
vim ~/.virtualenvs/my_project/bin/{postactivate,preactivate,predeactivate,etc}

# work in this env
workon my_project

Anda juga memiliki kait umum ~/.virtualenvs/{postactivate,postdeactivate,etc}yang disebut setiap kali Anda workon any_project.

Jadi, misalnya, memiliki garis export HISTFILE="$VIRTUAL_ENV/bash_history"di ~/virtualenvs/postactivatehook berarti bahwa $HISTFILEvariabel akan diperluas setiap kali ke proyek yang berbeda.

catalin.costache
sumber
3

Saya membutuhkan ini juga dan saya telah menghasilkan versi yang menggunakan variabel PROMPT_COMMAND Bash :

Nilai variabel PROMPT_COMMAND diperiksa sebelum Bash mencetak setiap prompt utama. Jika PROMPT_COMMAND diatur dan memiliki nilai bukan nol, maka nilai tersebut dieksekusi seperti jika telah diketik pada baris perintah.

Jadi saya katakan PROMPT_COMMAND = "check_for_local_history" di ~ / .bashrc.my, di mana check_for_local_historyfungsi saya yang memeriksa apakah perintah yang terakhir dieksekusi adalah perubahan direktori, dan ketika itu benar, ia memeriksa direktori baru saat ini untuk file .bash_history . Jika ada, gunakan sebagai file histori.

Inilah intisari lengkap: https://gist.github.com/gurdiga/dac8d2e7eb3056d6b839

Vlad GURDIGA
sumber
2

Salah satu trik yang saya gunakan untuk kerangka membangun sub-paket untuk suatu produk adalah dengan menggunakan sub-shell.

Untuk bash, Anda dapat membuat skrip shell seperti ini:

#!/bin/bash

export PROJECT_DIRECTORY=$(pwd)

exec bash --rcfile $HOME/.project-bashrc

Kemudian di dalam $HOME/.project-bashrckamu letakkan sesuatu seperti ini:

source $HOME/.bashrc
export HISTFILE="${PROJECT_DIRECTORY}/.bash_history"
cd "${PROJECT_DIRECTORY}"

Ini juga memungkinkan Anda menyesuaikan prompt di .project-bashrcfile, yang bisa berguna.

Saya tidak yakin bagaimana melakukan hal yang sama zsh. Anda harus mengganti ZDOTDIRvariabel, saya pikir. Tapi itu akan terlihat serupa.

Ciao!

docwhat
sumber
1

Lihatlah skrip logging saya di sini . Dengan menggunakan salah satunya, Anda dapat melacak direktori apa yang Anda masuki ketika Anda mengeluarkan setiap perintah. Anda dapat grepfile log untuk perintah atau informasi lainnya. Saya menggunakan versi panjang di rumah dan di tempat kerja.

Dijeda sampai pemberitahuan lebih lanjut.
sumber
Terima kasih - Saya akan melihat ini. Mungkin melakukan sesuatu yang dekat dengan apa yang saya butuhkan!
Simon
1

Anda mungkin tertarik pada plugin yang saya tulis bernama direktori-history untuk zsh.
Lihat di sini: https://github.com/tymm/directory-history

Meskipun tidak benar-benar sesuai dengan pekerjaan Anda di myproject alur kerja, itu harus sesuai dengan kebutuhan Anda.

Itu menciptakan sejarah yang mencakup direktori.
Ketika Anda mencari melalui histori Anda, pertama-tama Anda akan mendapatkan perintah dari direktori tempat Anda berada.
Jika tidak ada perintah yang tersisa untuk direktori itu, ia akan kembali ke sejarah global dan menyarankan perintah yang digunakan dalam direktori lain.

tymm
sumber
1

Jika Anda menginginkan sesuatu yang sederhana, Anda dapat memiliki .history.logfile seperti itu:

#!/bin/cat
some
relevant
commands

Kemudian menjalankan file akan catperintah-perintah yang Anda daftarkan di dalamnya.
Anda juga bisa mengelompokkan perintah-perintah itu dalam file terpisah berdasarkan fungsi sebagai konvensi:

.howto.datadump
.howto.restart

Ini memiliki keuntungan tambahan untuk bekerja di luar kotak dan tidak mencemari lingkungan Anda.

Reno
sumber
Atau Anda dapat menggunakan README.mdatau membuat .mdfile lain per topik dan mengarahkan mereka dari readme. Itu jika Anda memiliki antarmuka kontrol sumber ramah penurunan harga.
Reno
1

Untuk mendapatkan file histori lokal untuk direktori, saya menambahkan baris berikut ke perintah bash prompt saya.

if [ -f .local_history ] ; then tail -1 $HISTFILE >> .local_history ; fi

Perintah touch .local_historydalam direktori kemudian memberi saya file sejarah lokal untuk semua perintah yang dieksekusi di direktori itu, tanpa kehilangan file sejarah utama. Sesuatu yang serupa akan bekerja di zsh kurasa.

Aad Schippers
sumber
0

Dalam bash setidaknya, HISTFILE hanya dikonsultasikan pada awal contoh shell. Ide per-dir tidak akan berfungsi di sini, kecuali contoh 'workon' Anda di atas membuat instance shell.

Mungkin Anda bisa melihat sesuatu seperti

alias workon='script ./.history.log'

Tetapi skrip juga menciptakan subkulit.

Singkatnya, Anda mungkin perlu tingkat subkulit yang berantakan untuk membuatnya berfungsi.

Homolka yang kaya
sumber
Sial, aku berharap itu akan menjadi sesuatu yang sederhana. Bagaimanapun, terima kasih!
Simon
0

Saya telah bekerja di rumah perangkat lunak produksi tempat kami baru saja membuat pengguna dan grup baru untuk berbagai fungsi. Akun pengguna baru khusus untuk manajemen konfigurasi atau perangkat lunak dibangun dengan berbagai tingkat visibilitas ke area fungsional terkait lainnya melalui keanggotaan grup dan ACL, dan riwayat perintah yang dilakukan oleh, cmmgrakan disimpan ~cmmgr/.bash_history, bldmgrkata terkait akan disimpan ~bldmgr/.bash_history, dll. Sayangnya, untuk masuk, pengguna harus memiliki direktori login mereka. Oleh karena itu, area proyek diatur pada disk terpisah sama sekali. Kepemilikan pembuat file menunjukkan area fungsional mana yang membuat file di area proyek, yang sesuai .bash_historydapat diperiksa.

Pendekatan di atas, bagaimanapun, tidak memberi Anda rincian yang Anda inginkan, namun, itu memberi Anda kerangka bahwa ketika dikombinasikan dengan keanggotaan grup, pengguna dapat berganti grup newgrpyang secara efektif menciptakan shell dan lingkungan baru, dan kemudian menggunakan satu dari pendekatan yang diberikan dalam jawaban lain untuk mengubah ~/.bash_historyfile yang efektif ketika beralih topi untuk mengatakan, cmmgrsehingga newgrpdapat mengelola yang ~/.bash_historydigunakan dan disimpan per folder sebagai salah satu masuk dan keluar dari grup baru melalui newgrpperintah. Lihat man newgrp. Ada beberapa titik awal di sepanjang garis ini dalam jawaban lain untuk pertanyaan ini. Ini harus bekerja dengan paradigma grup UNIX - sebagian besar mur dan baut ditangani oleh startup shell dan keluar dari rutinitas sebagaimana dikendalikan olehnewgrpdoa. Lihat newgrp -l:

NAME
     newgrp -- change to a new group

SYNOPSIS
     newgrp [-l] [group]

DESCRIPTION
     The newgrp utility creates a new shell execution environment with modified real and effective group
     IDs.

     The options are as follows:

     -l      Simulate a full login.  The environment and umask are set to what would be expected if the user
             actually logged in again.
Billy McCloskey
sumber
0

Di sini saya menyajikan dua varian, tetapi hanya berlaku untuk Z Shell .

Varian 1

Inilah yang pertama kali saya pikirkan ketika membaca judul pertanyaan Anda. Dengan varian ini Anda dapat beralih antara dua mode riwayat dengan ALT+ h: Global atau lokal , di mana yang terakhir beralih ke riwayat per direktori secara otomatis pada chdir . Sejarah global mengakumulasikan semua perintah yang dikeluarkan.

  • Demonstrasi

    ~ source src / cd_history
    ~ gema sejarah global                                                
    sejarah global
    ~ mkdir foo bar                                                      
    ~ [ALT-h] 
    ~                          perhatikan indikator untuk sejarah lokal ->    +
    ~ cd foo +
    ~ / foo gema sejarah lokal di foo +
    sejarah lokal di foo
    ~ / foo fc -l +
        1 gema sejarah lokal di foo
    ~ / foo cd ../bar +
    ~ / bar gema sejarah lokal di bar +
    sejarah lokal di bar
    ~ / bar fc -l +
        1 gema sejarah lokal di bilah
    ~ / bar cd ../foo +
    ~ / foo fc -l +
        1 gema sejarah lokal di foo
        3 cd ../bar
    ~ / foo [ALT-h]                                           
    ~ / foo fc -l                                                          
       55 sumber src / cd_history
       64 gema sejarah global
       65 mkdir foo bar
       66 cd foo
       70 gema sejarah lokal di bar
       72 cd ../foo
       73 gema sejarah lokal di foo
       74 cd ../bar
    ~ / foo  
  • Script (untuk dimasukkan ~/.zshrcatau bersumber)

    # set options for shared history
    setopt prompt_subst
    setopt share_history
    setopt hist_ignorealldups
    
    # define right prompt as an indicator if local (i.e. per directory) history is enabled
    RPS1=' ${HISTLOC}'
    export HISTLOC=''
    
    # configure global history file and global/local history size
    export HISTGLOBAL=$HOME/.zsh_history
    touch $HISTGLOBAL
    export HISTSIZE=2000
    export SAVEHIST=2000
    
    # define wrapper function and key binding to switch between globel and per-dir history
    function my-local-history()
    {
      if [[ -z $HISTLOC ]]; then
        HISTLOC='+'
        chpwd
      else
        HISTLOC=''
        export HISTFILE=$HISTGLOBAL
        fc -A $HISTFILE
        fc -p $HISTFILE $HISTSIZE $SAVEHIST
      fi
      zle reset-prompt
    }
    zle -N my-local-history
    bindkey "^[h"    my-local-history
    
    # install hook function which is called upon every directory change
    chpwd () {
      if [[ ! -z $HISTLOC ]]; then
        fc -A $HISTGLOBAL $HISTSIZE $SAVEHIST
        export HISTFILE=$PWD/.zsh_history
        fc -p $HISTFILE $HISTSIZE $SAVEHIST
        touch $HISTFILE
      fi 
    }

Varian 2

Memikirkannya lagi, sepertinya sejarah per-dir terlalu baik dan Anda juga menggambarkan lebih banyak sejarah per-proyek di badan pertanyaan Anda. Jadi saya datang dengan varian lain dengan fungsi workon untuk beralih antar proyek. Setiap proyek memiliki file riwayatnya sendiri ~/.zsh_projhistory_[name].

  • Demonstrasi

    ~ source src / proj_history 
    ~ gema sejarah global                                                                    
    sejarah global
    ~ [ALT-h]                                                               [gunakan workon]
    ~ workon foo [gunakan workon]
    ~ Perintah echo di project foo [on proj foo]
    perintah dalam project foo
    ~ fc -l [on proj foo]
        1 perintah echo di project foo
    ~ workon bar [di proj foo]
    ~ echo proj lain, bernama bar [pada proj bar]
    proj lain, bernama bar
    ~ fc -l [pada bilah proj]
        1 gema proj lain, bernama bar
    ~ workon foo [pada bilah proj]
    ~ fc -l [on proj foo]
        1 perintah echo di project foo
        3 workon bar
    ~ [ALT-h]                                                              [on proj foo]
    ~
    ~ fc -l                                                                                   
       31 gema sejarah global
       36 gema proj lain, bernama bar
       38 workon foo
       39 perintah echo di project foo
       40 workon bar
    ~ ls -1 .zsh_ *
    .zsh_history
    .zsh_projhistory_bar
    .zsh_projhistory_foo
  • Script (untuk dimasukkan ~/.zshrcatau bersumber)

    # set options for shared history
    setopt prompt_subst
    setopt share_history
    setopt hist_ignorealldups
    
    # define right prompt as an indicator if local (i.e. per directory) history is enabled
    RPS1=' ${HISTLOC}'
    export HISTLOC=''
    
    # configure global history file and global/local history size
    export HISTGLOBAL=$HOME/.zsh_history
    touch $HISTGLOBAL
    export HISTFILE=$HISTGLOBAL
    export HISTSIZE=2000
    export SAVEHIST=2000
    
    # define wrapper function and key binding to switch between globel and per-dir history
    function my-local-history()
    {
      if [[ -z $HISTLOC ]]; then
        if [[ -z $HISTLOC ]]; then
          HISTLOC='+'
          [[ -z "$HISTPROJ" ]] && HISTLOC='[use workon]' || workon "$HISTPROJ"
        fi
      else
        HISTLOC=''
        export HISTFILE=$HISTGLOBAL
        fc -A $HISTFILE
        fc -p $HISTFILE $HISTSIZE $SAVEHIST
      fi
      zle reset-prompt
    }
    zle -N my-local-history
    bindkey "^[h"    my-local-history
    
    # function to change project
    workon () {
      if [[ -z "$1" ]]; then
        echo Usage: workon [project name]
        return 1
      fi
      export HISTPROJ="$1"
      if [[ ! -z $HISTLOC ]]; then
        fc -A $HISTGLOBAL $HISTSIZE $SAVEHIST
        export HISTFILE=$HOME/.zsh_projhistory_"$HISTPROJ"
        fc -p "$HISTFILE" $HISTSIZE $SAVEHIST
        touch "$HISTFILE"
        HISTLOC="[on proj $HISTPROJ]"
      fi 
    }
mpy
sumber
0

Setelah bekerja di satu area untuk sementara waktu.

histori> hist1.txt lalu nanti histori> hist2.txt

Terkadang saya menggunakan tanggal untuk nama file. history> hist20180727.txt

Dengan cara ini ada sejarah perintah terbaru untuk setiap direktori.

John
sumber