2008-12-03 16 views
38

Tôi đang cố ngăn chặn bash lưu các lệnh trùng lặp vào lịch sử của mình. Dưới đây là những gì tôi đã có:Ngăn các mục trùng lặp được lưu trong lịch sử bash

shopt -s histappend 
export HISTIGNORE='&:ls:cd ~:cd ..:[bf]g:exit:h:history' 
export HISTCONTROL=erasedups 
export PROMPT_COMMAND='history -a' 

Điều này làm việc tốt khi tôi đăng nhập và .bash_history có trong bộ nhớ. Ví dụ:

$ history 
    1 vi .bashrc 
    2 vi .alias 
    3 cd /cygdrive 
    4 cd ~jplemme 
    5 vi .bashrc 
    6 vi .alias 

$ vi .bashrc 

$ history 
    1 vi .alias 
    2 cd /cygdrive 
    3 cd ~jplemme 
    4 vi .alias 
    5 vi .bashrc 

$ vi .alias 

$ history 
    1 cd /cygdrive 
    2 cd ~jplemme 
    3 vi .bashrc 
    4 vi .alias 

$ exit 

Nhưng khi tôi đăng nhập lại, tập tin lịch sử của tôi trông như thế này:

$ history 
    1 vi .bashrc 
    2 vi .alias 
    3 cd /cygdrive 
    4 cd ~jplemme 
    5 vi .bashrc 
    6 vi .alias 
    7 vi .bashrc 
    8 vi .alias 

Tôi đang làm gì sai?

CHỈNH SỬA: Xóa shoptPROMPT_COMMAND dòng từ .bashrc không khắc phục được sự cố.

+1

Bạn đã bao giờ giải quyết vấn đề này chưa? Tiểu sử/etc/của tôi trông như thế này (trên mac) và tôi có cùng một vấn đề: # http://blog.macromates.com/2008/working-with-history-in-bash/ # http: //www.ducea.com/2006/05/15/linux-tips-take-control-of-your-bash_history/ xuất khẩu HISTCONTROL = erasedups xuất khẩu HISTSIZE = 10000 xuất khẩu HISTTIMEFORMAT đã = "% F-% T% t " shopt -s histappend (Cố gắng định dạng nửa này khá, không dễ) – joedevon

+0

Xem câu hỏi này http://unix.stackexchange.com/questions/48713/how-can-i-remove-duplicates -in-my-bash-history-preserving-order – Nathan

+1

Đây là một vấn đề vốn có trong lập trình và liên quan đến các công cụ lập trình cụ thể sử dụng. Tôi băn khoăn rằng câu hỏi này sẽ được coi là "off-topic" (nhiều hơn bởi ít nhất 5 người). Một dư thừa. Bash_history là một khó chịu lâu dài cho tôi bây giờ giải quyết. Câu hỏi này có thể được chuyển đến trang web Unix stackexchange. –

Trả lời

5
export HISTCONTROL=ignoreboth 
7

Vấn đề chắc chắn là histappend. Đã kiểm tra và xác nhận trên hệ thống của tôi.

môi trường có liên quan của tôi là:

$ set | grep HIST 
HISTFILE=/Users/hop/.bash_history 
HISTFILESIZE=500 
HISTIGNORE=' *:&:?:??' 
HISTSIZE=500 
$ export HISTCONTROL=erasedups 
$ shopt | grep hist 
cmdhist   on 
histappend  off 
histreedit  off 
histverify  off 
lithist   off 

Bây giờ tôi nghĩ về nó, vấn đề có lẽ là với history -a. history -w nên ghi lại lịch sử hiện tại mà không có bất kỳ bản sao nào, do đó hãy sử dụng nếu bạn không ngại các vấn đề tương tranh.

2

Dưới đây là những gì tôi sử dụng ..

[[email protected] ~]$ grep HIST .alias* 
.alias:HISTCONTROL="erasedups" 
.alias:HISTSIZE=20000 
.alias:HISTIGNORE=ls:ll:"ls -altr":"ls -alt":la:l:pwd:exit:mc:su:df:clear:ps:h:history:"ls -al" 
.alias:export HISTCONTROL HISTSIZE HISTIGNORE 
[[email protected] ~]$ 

và làm việc

[[email protected] ~]$ pwd 
/Users/XXX 
[[email protected] ~]$ pwd 
/Users/XXX 
[[email protected] ~]$ history | grep pwd | wc -l 
     1 
+2

Cảm ơn Venu. Vấn đề tôi gặp phải là hơi khác một chút. Giả sử có 20 "ls" trong lịch sử. Bằng cách nhập "ls", nó sẽ loại bỏ các bản sao để lịch sử của bạn ngắn hơn .... ít nhất là trong phiên. Nhưng thoát ra và bắt đầu một phiên mới và nó lưu các công cụ mới và giữ lại các bản sao cũ. Hoàn tác hầu hết các tiện ích của các lần xóa. #Facepalm. – joedevon

+0

Đã thêm thứ gì đó rất giống với .bash_profile của tôi: 'xuất HISTIGNORE = ls:" ls -la ":" cd .. ":" cd ~ ": pwd: thoát: su:" sudo -i ": clear: ps: "ps $ export HISTSIZE = 20000 export HISTCONTROL =" erasedups "' – humbolight

1

bên .bash_profile của bạn thêm

alias hist="history -a && hist.py" 

sau đó đặt này trên con đường của bạn như hist.py và làm cho tệp thực thi được

#!/usr/bin/env python 
f = open('/Users/joe/.bash_history') 
l = f.readlines() 
l.reverse() 
short = [] 
for s in l: 
    if s.rstrip() not in short: 
     short.append(s.rstrip()) 
short.reverse() 
for s in short: 
    print s 

ngay bây giờ khi bạn muốn danh sách ngắn chỉ cần nhập hist

31

Theo như tôi biết, bạn không thể thực hiện những gì mình muốn. Tôi thấy điều này như một lỗi trong quá trình xử lý lịch sử của bash có thể được cải thiện.

export HISTCONTROL=ignoreboth:erasedups # no duplicate entries 
shopt -s histappend      # append history file 
export PROMPT_COMMAND="history -a"  # update histfile after every command 

Điều này sẽ giữ lịch sử bộ nhớ độc đáo, nhưng nó không giữ lịch sử trong tệp độc đáo. history -a sẽ viết lệnh mới vào tệp trừ khi nó giống với lệnh ngay trước nó. Nó sẽ không thực hiện khử trùng hoàn toàn như cài đặt erasedups trong bộ nhớ.

Để xem tính năng silliness này hoạt động, hãy bắt đầu phiên thiết bị đầu cuối mới, kiểm tra lịch sử và bạn sẽ thấy các mục lặp lại, giả sử ls. Bây giờ chạy lệnh ls và tất cả các ls trùng lặp sẽ bị xóa khỏi lịch sử trong bộ nhớ, chỉ để lại lần cuối cùng. Lịch sử bộ nhớ trở nên ngắn hơn khi bạn chạy các lệnh được sao chép trong tệp lịch sử, nhưng bản thân tệp lịch sử vẫn tiếp tục phát triển.

Tôi sử dụng tập lệnh của riêng mình để xóa tệp lịch sử theo yêu cầu.

# remove duplicates while preserving input order 
function dedup { 
    awk '! x[$0]++' [email protected] 
} 

# removes $HISTIGNORE commands from input 
function remove_histignore { 
    if [ -n "$HISTIGNORE" ]; then 
     # replace : with |, then * with .* 
     local IGNORE_PAT=`echo "$HISTIGNORE" | sed s/\:/\|/g | sed s/\*/\.\*/g` 
     # negated grep removes matches 
     grep -vx "$IGNORE_PAT" [email protected] 
    else 
     cat [email protected] 
    fi 
} 

# clean up the history file by remove duplicates and commands matching 
# $HISTIGNORE entries 
function history_cleanup { 
    local HISTFILE_SRC=~/.bash_history 
    local HISTFILE_DST=/tmp/.$USER.bash_history.clean 
    if [ -f $HISTFILE_SRC ]; then 
     \cp $HISTFILE_SRC $HISTFILE_SRC.backup 
     dedup $HISTFILE_SRC | remove_histignore >| $HISTFILE_DST 
     \mv $HISTFILE_DST $HISTFILE_SRC 
     chmod go-r $HISTFILE_SRC 
     history -c 
     history -r 
    fi 
} 

Tôi muốn nghe những cách thanh lịch hơn để thực hiện việc này.

Lưu ý: tập lệnh sẽ không hoạt động nếu bạn bật dấu thời gian trong lịch sử qua HISTTIMEFORMAT.

Bash có thể cải thiện tình hình bằng cách

  1. sửa chữa history -a chỉ ghi dữ liệu mới nếu nó không phù hợp với bất kỳ lịch sử trong bộ nhớ, không chỉ là người cuối cùng.
  2. lịch sử de-trùng lặp khi tệp được đọc nếu cài đặt erasedups được đặt. Một đơn giản history -w trong một thiết bị đầu cuối mới sau đó sẽ làm sạch tệp lịch sử thay vì tập lệnh ngớ ngẩn ở trên.
+3

Câu trả lời đúng. Nếu bạn muốn giữ nguyên thứ tự thời gian (thay vì thứ tự đầu vào) cho lệnh của bạn, hãy sửa đổi 'dedup()' bằng cách thay thế 'awk' x [$ 0] ++ '$ @ 'với' tac $ @ | awk'! x [$ 0] ++ '| tac'. – trusktr

+6

@raychi Chỉ cần kiểm tra xem, nếu đây vẫn là giải pháp tốt nhất khi chúng ta tiếp cận 2014 ? –

+1

Mở rộng nhận xét của @ trusktr, sửa 'lịch sử -a' thành chỉ ghi dữ liệu mới sẽ không hoạt động, vì thực tế nó nên xóa lần xuất hiện trước đó và thêm lần xuất hiện mới nhất. Tôi nghi ngờ đó là do sự phức tạp này ' đã giải quyết để chỉ xóa các bản sao liên tiếp. – trss