这是在分屏xterm上运行的最终产品,从基本的外壳默认值到仅使用几个命令即可工作:
比屏幕截图中展示的方法更粗糙的方法看起来像这样:
PS1='$( { date ; fc -l -0 ; } >${TGT_PTY} )'$PS1
当${TGT_PTY}
您tty
实际在想要输出的屏幕上运行交互式shell时,从命令中得到的结果将是什么。或者,实际上,您可以使用任何可写文件,因为它本质上仅是文件重定向的目标。
我将pty语法用于伪终端,因为我假设它是某种xterm,但您可能也很容易将vt专用化-并且流式传输的历史记录始终只是CTRL-ALT-Fn
键组合。如果是我,我可以将这两个概念结合起来,并在专用的vt上作为一个会话screen
或tmux
会话。但是我离题了。
在刚启动的计算机上,我在/bin/login
典型的Linux getty
控制台上看到了典型的提示。我按一下CTRL-ALT-F2
即可访问一个不太典型的kmscon
控制台,该控制台的行为更像是xterm
a而不是a tty
。我输入命令tty
并收到响应/dev/pts/0
。
通常,xterms使用伪终端将单个终端设备多路复用为多个终端 -因此,如果您要通过在终端选项卡或窗口之间切换来在X11中执行类似的操作,您可能也会收到类似的输出/dev/pts/[0-9]*
。但是使用CTRL-ALT-Fn
组合键访问的虚拟终端控制台是真正的终端设备,因此会获得自己的/dev/tty[0-9]*
名称。
这就是为什么登录控制台2后,当我tty
在提示符下键入时的响应是,/dev/pts/0
但是当我在控制台1上执行相同的操作时,输出是/dev/tty1
。无论如何,回到控制台2然后执行:
bash
PS1='$( { date ; fc -l -0 ; } >/dev/tty1 )'$PS1
没有明显的效果。我继续输入一些命令,然后CTRL-ALT-F1
再次按切换到控制台1 。在这里,我发现重复的条目看起来像<date_time>\n<hist#>\t<hist_cmd_string>
在控制台2上键入的每个命令一样。
但是,除非直接写入终端设备,否则另一个选项可能类似于:
TGT_PTY=
mkfifo ${TGT_PTY:=/tmp/shell.history.pipe}
{ echo 'OPENED ON:'
date
} >${TGT_PTY}
然后也许...
less +F ${TGT_PTY}
粗略的提示命令不符合您的要求-都没有格式字符串,date
也没有格式选项fc
-但它的机制并不需要太多:每次您的提示呈现上一个历史记录命令时,当前日期和时间都被写到${TGT_PTY}
您指定的文件。就这么简单。
观看和打印shell历史记录是fc
的主要目的。它是内置的外壳,即使date
不是。中zsh
fc
可以提供各种精美的格式设置选项,其中一些适用于时间戳。当然,如你上面的注意,bash
的history
可以做同样的。
为了获得更清晰的输出,您可以使用我在这里更好地解释过的技术在当前shell中设置持久跟踪变量,尽管必须在提示序列中对其进行跟踪并在子shell中对其进行处理。
这是格式化为您的规格的便携式方法:
_HIST() { [ -z ${_LH#$1} ] ||
{ date "+${1}%t[%F %T]"
fc -nl -0
} >${TGT_PTY}
printf "(_LH=$1)-$1"
}
: "${_LH=0}"
PS1='${_LH##*[$(($(_HIST \!)))-9]}'$PS1
我实现了last_history计数器$_LH
,该计数器仅跟踪最新更新,因此您不会两次写出相同的历史记录命令-例如,仅用于按Enter键。要使变量在当前外壳中递增,需要进行一些争吵,以便即使在子外壳中调用该函数也可以保留其值-再次在链接中对此进行了详细说明。
它的输出看起来像 <hist#>\t[%F %T]\t<hist_cmd>\n
但这只是完全可移植的版本。使用bash
它可以用更少的精力并且仅通过实现shell内置函数来完成-当您认为这是每次按下时都会运行的命令时,这可能是合乎需要的[ENTER]
。有两种方法:
_HIST() { [ -z ${_LH#$1} ] || {
printf "${1}\t[%(%F %T)T]"
fc -nl -0
} >${TGT_PTY}
printf "(_LH=$1)-$1"
}
PROMPT_COMMAND=': ${_LH=0};'$PROMPT_COMMAND
PS1='${_LH##*[$(($(_HIST \!)))-9]}'$PS1
另外,您也可以使用bash
的history
命令_HIST
以这种方式定义函数:
_HIST() { [ -z ${_LH#$1} ] ||
HISTTIMEFORMAT="[%F %T]<tab>" \
history 1 >${TGT_PTY}
printf "(_LH=$1)-$1"
}
这两种方法的输出都看起来像:<hist#>\t[%F %T]\t<hist_cmd>\n
尽管该history
方法包括一些前导空格。不过,我相信该history
方法的时间戳会更加准确,因为我认为他们无需等待引用的命令完成就可以获取其戳记。
你可以不惜一切在两种情况下跟踪任何状态下,只要你以某种方式与过滤信息流uniq
-因为你可能会做mkfifo
,因为我前面提到的。
但是在这样的提示中进行操作意味着仅在需要时才通过更新提示的方式来始终对其进行更新。这很简单。
您可能还会执行与您正在执行的操作类似的操作,tail
而是进行设置
HISTFILE=${TGT_PTY}
fn+1
进行比较,那么效果很好,最初显示速度更快!谢谢!