如何保存包含所有命令行输入和输出的文本文件而不保存 ANSI 字符?

如何保存包含所有命令行输入和输出的文本文件而不保存 ANSI 字符?

我正在运行最新的 mac 操作系统并使用 zshell,但在编写 shell 脚本时遇到问题。我的大部分工作都是通过命令行完成的,并且希望有一个 bash 脚本自动保存和记录我的所有输入命令和输出。

我最明显的选择是 bash“脚本”命令,通常在命令行上启动,如下所示

script -a <filename>.txt

我写了一个shell脚本,log.sh其内容如下:

#! /bin/sh
echo "Welcome to the jungle."

# get date
now=$(date +%Y_%m_%d)

# create filename
fname='log_'$now'.txt'

# file save location
floc=~/path/to/directory/$fname

# start script
script -a -q  $floc

这将启动一个脚本,其中文件名是今天的日期并保存在指定目录中。但是,除了写入文件的内容之外,这工作得很好。我得到的不仅仅是我所期望的计划文本输入/输出,而是我认为是 ANSI 字符的内容,这些字符使文件难以阅读。

我的命令行如下所示:

~$ bash log.sh      
Welcome to the jungle.
~$ echo "Hello world"
Hello world
~$ exit

Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.

以及它是如何记录在日志文件中的:

[1m[7m%[27m[1m[0m                                                                                                  
 
]7;file://<myname>/Users/<myusername>
[0m[27m[24m[J[36m<myusername>  [38;5;246m~[39m$ [K[?2004heecho "Hello world! "[?2004l

Hello world
[1m[7m%[27m[1m[0m                                                                                                  
 
]7;file://<myname>/Users/<myusername>
[0m[27m[24m[J[36m<myusername> [38;5;246m~[39m$ [K[?2004heexit[?2004l


Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.

我知道创建文件后有几种方法可以处理 ANSI 键,例如使用命令cat显示文本,或使用 perl 脚本删除键;但是,cat当我尝试查看大文件时,使用该命令很烦人,而且必须手动清理文件也很乏味。有什么方法可以记录我的命令行输入和输出没有ANSI 键?

谢谢你!

答案1

简单的方法是查看带有less -R.这并不完全是您所要求的,但无论如何可能会有所帮助。

答案2

这似乎有效:

#!/usr/bin/env zsh
{
    # Create a named pipe, using a temp file name.
    mkfifo -m 600 ${fifo::=$(mktemp -u)}

    logFile="~/logs/log-$(date +%F-%H-%M-%S).txt"
    print "Logging to $logFile"

    # Launch the filter in the background (&), so it will
    # run in parallel with the script utility.
    # This will read from the named pipe, remove the ansi
    # color escapes, and write the result to the log.
    # (perl source: https://superuser.com/a/1388860).
    perl -pe 's/\e\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]//g;
              s/\e[PX^_].*?\e\\//g;
              s/\e\][^\a]*(?:\a|\e\\)//g;
              s/\e[\[\]A-Z\\^_@]//g;' \
        < $fifo > ${~logFile} &

    # Get the process id of the background process.
    fifoPid=$!

    # Launch the script utility, capturing data from the
    # interactive shell. -F ensures writes are immediately
    # available in other processes.
    script -q -F $fifo
    # script -q -F $fifo bash

    # The background process will end when the script
    # utility closes its handle to the fifo, i.e. when the
    # shell launched by 'script' exits. But it may not exit
    # immediately, so it could be running when we get to
    # this point. This will bring it to the foreground, just
    # in case some other actions follow this script.
    wait $fifoPid

} always {
    # cleanup temp fifo.
    if [[ -p $fifo ]] rm $fifo
}

这使用了一个命名管道以便script实时过滤输出。您还可以在启动的 shell 程序中将清理过滤器作为后处理来运行script,但这并不是那么有趣。

相关内容