我可以从CLI缓存Linux上的命令输出吗?

Ric*_*rdo 11 bash command-line caching command-line-interface

我正在寻找' cacheme '命令的实现,它' memoizes'ARGV中的任何输出.如果它从未运行它,它将运行它并稍微记住输出.如果它运行它,它只会复制文件的输出(甚至更好,输出和错误分别为&1和&2).

让我们假设有人写了这个命令,它会像这样工作.

$ time cacheme sleep 1    # first time it takes one sec
real   0m1.228s
user   0m0.140s
sys    0m0.040s

$ time cacheme sleep 1    # second time it looks for stdout in the cache (dflt expires in 1h)
#DEBUG# Cache version found! (1 minute old)

real   0m0.100s
user   0m0.100s
sys    0m0.040s
Run Code Online (Sandbox Code Playgroud)

这个例子有点傻,因为它没有输出.理想情况下,它将在sleep-1-and-echo-hello-world.sh等脚本上进行测试.

我创建了一个小脚本,在/ tmp /中使用完整命令名和用户名的哈希创建一个文件,但我很确定已存在的东西.

你知道这些吗?

err*_*ror 5

通过添加到期时间作为可选参数,在某种程度上改进了上述解决方案。

#!/bin/sh
# save as e.g. $HOME/.local/bin/cacheme
# and then chmod u+x $HOME/.local/bin/cacheme
VERBOSE=false
PROG="$(basename $0)"
DIR="${HOME}/.cache/${PROG}"
mkdir -p "${DIR}"
EXPIRY=600 # default to 10 minutes
# check if first argument is a number, if so use it as expiration (seconds)
[ "$1" -eq "$1" ] 2>/dev/null && EXPIRY=$1 && shift
[ "$VERBOSE" = true ] && echo "Using expiration $EXPIRY seconds"
CMD="$@"
HASH=$(echo "$CMD" | md5sum | awk '{print $1}')
CACHE="$DIR/$HASH"
test -f "${CACHE}" && [ $(expr $(date +%s) - $(date -r "$CACHE" +%s)) -le $EXPIRY ] || eval "$CMD" > "${CACHE}"
cat "${CACHE}"
Run Code Online (Sandbox Code Playgroud)

  • 这个东西很好用,有人用过吗?所需的功能、文档、垃圾收集(当前过期的缓存项仅在被覆盖时才删除)、各种标志(仅使用缓存、缓存标准错误、缓存退出代码)和一些 POSIX 脚本优化。 (2认同)

are*_*lek 5

我已经为 bash 实现了一个简单的缓存脚本,因为我想加快 gnuplot 中管道 shell 命令的绘图速度。它可用于缓存任何命令的输出。只要参数相同并且传入参数的文件没有改变,就会使用缓存。系统负责清理。

#!/bin/bash

# hash all arguments
KEY="$@"

# hash last modified dates of any files
for arg in "$@"
do
  if [ -f $arg ]
  then
    KEY+=`date -r "$arg" +\ %s`
  fi
done

# use the hash as a name for temporary file
FILE="/tmp/command_cache.`echo -n "$KEY" | md5sum | cut -c -10`"

# use cached file or execute the command and cache it
if [ -f $FILE ]
then
  cat $FILE
else
  $@ | tee $FILE
fi
Run Code Online (Sandbox Code Playgroud)

您可以命名脚本cache,设置可执行标志并将其放入您的PATH. 然后只需在任何命令前加上前缀cache即可使用它。


dim*_*414 5

bash-cache的作者在这里进行了更新。我最近发布了bkt一个用于子进程缓存的 CLI 和 Rust 库。这是一个简单的例子:

# Execute and cache an invocation of 'date +%s.%N'
$ bkt -- date +%s.%N
1631992417.080884000

# A subsequent invocation reuses the same cached output
$ bkt -- date +%s.%N
1631992417.080884000
Run Code Online (Sandbox Code Playgroud)

它支持许多功能,例如异步刷新 (--stale--warm)、命名空间缓存 ( --scope),以及可选择关闭工作目录 ( --cwd) 和选择环境变量 ( --env)。有关更多信息,请参阅自述文件。

它仍然是一项正在进行的工作,但它很实用且有效!我已经在使用它来加速我的 shell 提示符和许多其他常见任务。