是否可以history -w
从 ruby 脚本运行底层 bash shell?
或者更好的是,是否可以在仅知道其 pid 的情况下运行 bash shell 的内置命令?
我发现的唯一方法是捕获信号,trap "history -w" SIGUSR1
然后将信号发送到进程,但我不确定这是否是一种好的做法,而且 bash 不使用 USR1,而且这样我最多可以执行 2 个命令(USR1 和 USR2)。而且我必须在使用它之前定义 trap。
我在 Mac 上,所以没有 SIGRTMIN..SIGRTMAX。
我为什么需要这个:
我创建了 ruby shell 脚本dt
,它在当前工作目录旁边打开新选项卡,然后我写道新标签页可以做同样的事情,但即使 tab 正忙于运行某些东西也可以做到这一点(我称之为使用火花dt
)。但是,如果重复选项卡中的历史记录也相同,并且我可以使用,那就更好了alias dt='history -w; dt'
,但是我该如何做到这一点newTabHere.app
?
答案1
除了在标准输入中输入命令外,没有现成的方法可以让 shell 执行命令。最简单的方法是让 bash 检查某个文件,或运行history -w
,作为PROMPT_COMMAND
(每次提示前执行的命令)的一部分。
我认为你实际上想要的是Bash 终端窗口之间的实时历史记录导出,也许更好的 Bash 历史记录。
您也可以考虑使用嘚(在大多数 Linux/OSX/其他 unix 软件包存储库中可用)inc_append_history
及其share_history
选项。
答案2
对于这个特定的用例,我建议只添加history -w
到您的PROMPT_COMMAND
(或在随后调用的 shell 函数中)。
更一般地,我建议为外部请求的命令建立一个队列,并使用PROMPT_COMMAND
它们来运行:
run_prompt_queue() {
local f
for f in ~/.bash_queue.d/$$-*
do
[[ -f $f ]] || continue # still works without nullglob
. "$f"
rm -fv "$f"
done
}
PROMPT_COMMAND+=$'\n run_prompt_queue'
rm -v "$HOME/.bash_queue.d/$$-"* # clear random leftovers when PID is recycled
然后在您的 Python 脚本中,创建一个包含您想要运行的命令的文件,然后将其重命名为sprintf("%s/.bash_queue.d/%u,%s", sys.env("HOME"), pid_of_bash, your_unique_suffix)
。
pid_of_bash
可能是sys.getppid()
,sys.getsid()
但这可能会根据脚本的嵌套级别而有所不同。
显然,您可以选择自己的约定来命名文件,但我强烈建议您至少作为一个选项包含目标 shell 的 PID。
如果您不关心哪个特定的 shell 您也可以基于 pgrp、sid、tty、一天中的时间等进行触发)
重要提示:确保没有其他人可以写入您的队列目录。