如何以编程方式访问C中的bash命令历史记录?

如何以编程方式访问C中的bash命令历史记录?,c,bash,C,Bash,我讨厌bash'history'命令。它从未找到我想要的历史记录项。有时我可以通过“历史| grep XXX”得到我想要的,但通常是历史太长(点击次数超过400次!耶)或太短(点击次数不超过0次) 我想,为什么我不写一个小小的“history helper”命令,让我基本上“star”特定的历史项目,并使它们始终出现在我的历史中,同时有一个全局星列表和一个cwd特定的星列表 听起来很棒。因此,我天真地试图通过这样做来阅读历史: system("history > blah") FILE *

我讨厌bash'history'命令。它从未找到我想要的历史记录项。有时我可以通过“历史| grep XXX”得到我想要的,但通常是历史太长(点击次数超过400次!耶)或太短(点击次数不超过0次)

我想,为什么我不写一个小小的“history helper”命令,让我基本上“star”特定的历史项目,并使它们始终出现在我的历史中,同时有一个全局星列表和一个cwd特定的星列表

听起来很棒。因此,我天真地试图通过这样做来阅读历史:

system("history > blah")
FILE *fp = fopen("blah", "r")
哦,那没用。啊,我明白了,system()命令在它自己的上下文中运行,不能访问bash历史记录。德拉茨。好的,我将尝试阅读~/.bash\u history

function cd {
    builtin cd "$@"
    if [ -f .cwdhist ]; then
        history -r .cwdhist
    fi
}
巴巴~不。只有在最后一次调用a)history-w或b)调用退出shell之前,才会得到历史记录

那么,问题:我如何以编程方式访问C中当前的bash历史记录?

(注意:不,不是~/.bash_history中的内容,当前的历史,当您在提示符中键入“history”时所看到的确切输出;还有,您为什么要问C?为什么不…但实际上,因为我已经有了一个方便的ncurses包装器,我将使用它在普通终端上进行奇特的自动完成和子选择历史搜索…)

编辑:请,如果你有什么有用的贡献,我很高兴听到它,但我有点厌倦了像“你应该阅读bash历史手册页”这样的评论


我读过。没有任何东西允许我“启动”历史记录项并使其始终出现在我的历史记录中,也没有任何东西允许我维护每个目录的历史记录上下文。这些都是历史所不支持的。我很感激。这就是为什么我想为我的特定目的编写一个helper函数。如果你有类似“也许你应该多读一些历史手册”的评论,请不要回应;这并没有真正解决我的问题。:)

简短回答

您可以在
history
source中找到答案,它是
bash
builtin

长答案

看起来您只需要阅读一下
帮助历史记录
man bash

您的历史文件正在不断地使用shell重写(取决于您的设置。默认情况下,它是在注销/退出时完成的)。您需要破解shell以添加特定的规则来实现这一点。但是你离这个水平还很远

只是因为如果您非常接近它,您没有从
c
=)中询问如何使用.bash_历史

但是,还有另一种改进历史记录的方法:增加历史记录的大小,限制重复读取,并使所有命令在执行后立即进入历史记录。为此,您需要将以下变量放入
.bashrc
中:

PROMPT_COMMAND='history -a;history -n'

export HISTCONTROL=ignoredups
export HISTTIMEFORMAT='%F %T '
export HISTSIZE=100500

shopt -s histappend
shopt -s cmdhist
此外,还可以防止使用录制特定命令

export HISTIGNORE="unwanted_command:unwanted_mask*"

希望它能帮助您。

工作目录特定历史记录

function cd {
    builtin cd "$@"
    if [ -f .cwdhist ]; then
        history -r .cwdhist
    fi
}
星号历史命令

基本原理是结合一些shell函数逻辑来编写和读取历史助手程序的历史

function histedit {
    history -a
    historyhelper $HOME/.bash_history $HOME/.histout
    history -c
    history -r $HOME/.histout
}

history-a
命令将所有最近的历史附加到历史文件中。然后该函数调用您的历史记录助手。您可以将任何需要的smarts放入此程序,确保您喜欢的命令在历史记录中,如果没有,则添加它们,然后将其输出保留在
.historut
(或其他任何内容)中。然后该函数继续、清除并重新加载历史记录。也许它应该避免清除历史。或者,如果historyhelper返回非零退出状态,则该函数应该中止。你可以在这里做各种各样的事情。

你能做的最接近的事情是

alias cmd="history | cmd"

然后阅读应用程序中的标准输入。

简短回答:你不能。长回答是:你可以(只要你获得了bash的源代码,并根据自己的意愿对其进行攻击)。你会明白答案有多长……为什么不编写一个helper bash函数(或bash别名),它可以调用也可以不调用这个“history helper”程序,也可以不通过stdin传递信息?@BrianAgnew我以前尝试过破解bash。不用了,谢谢/伊格纳西奥所说的,但是你应该考虑签出<代码> ZSH ,它基本上是一个BASH后裔,它有一些非常好的特征,包括更复杂的完成(甚至可以完成很多程序的主机名和命令行参数)。这将导致从历史记录列表中排除以空格开头的任何命令。我在这里提到它是因为你在
HISTIGNORE
中提到了一个面具。您可以使用
HISTCONTROL=ignorespace:ignoredups
HISTCONTROL=ignoreboth
作为快捷方式。这很有趣,但似乎与我的问题无关?