首页 > 解决方案 > 在运行命令 bash 之前保存输入

问题描述

我正在尝试将我输入的命令及其各自的输出保存在一个文件中。
我目前在做什么:

mylog() {
    echo "----------------" >> ${PWD}/cmds.log
    echo "$@" >> ${PWD}/cmds.log
    # read foo # Tried reading the piped value in to
    # echo "$foo" >> ${PWD}/cmds.log
    # MYCMD="${@}"
    # echo "$MYCMD" >> ${PWD}/cmds.log
    "$@" | tee -a ${PWD}/cmds.log
}

它目前mylog cat file.txt | mylog sort
的功能如下: 输出cmds.log为:

----------------
cat file.txt
----------------
sort
....
output from cat
...
output from sort
...

我想要的是:

----------------
cat file.txt
....
output from cat
...
----------------
sort
...
output from sort
...

在代码中,您可以看到我尝试使用 read 并遵循此处描述的其他方法。
我也试过这样做VAR=${@},但这只是保存了两次命令并且没有执行它。

知道如何实现我的目标吗?

稍微相关的是,我像这样手动保存终端输出,而不是使用,script因为交互式外壳会导致很多转义字符等被捕获。

标签: bash

解决方案


您修改后的脚本...

#!/usr/bin/env bash

mylog() {
    local output="log"
    
    # This is the key part right here. The 'tac' command here
    # prints stdin in reverse. To do this, it must read _all_
    # of stdin, so it buffers until it reads everything. Of course,
    # we must use two 'tac's so stdin doesn't actually get reversed.
    # You could also use `sponge(1)` here, but that does not come standard
    # on all Linux distributions / MacOS
    local buffer="$("$@" | tac | tac)"

    # Nothing below will be printed until 'buffer' is completely filled with stdin
    {
        echo "----------------"
        echo "$@"
        echo "----------------"
        echo "$buffer"
        echo
    } >> "$output"

    printf "%s" "$buffer" 
}

rm -f log
mylog cat file.txt | mylog sort >/dev/null

所结果的log

----------------
cat file.txt
----------------
bravo
alfa
charlie
delta
echo

----------------
sort
----------------
alfa
bravo
charlie
delta
echo



推荐阅读