Você pode colocar o resultado em um arquivo e depois lê-lo de volta a partir desse arquivo ...
tmpDir=/tmp/$$
rm -rf "$tmpDir"
mkdir "$tmpDir"
echo cmd1 > "$tmpDir"/cmd1_stdout 2> "$tmpDir"/cmd1_stderr
echo $? > "$tmpDir"/cmd1_exitcode
# Retrieving output of cmd1:
( cat "$tmpDir"/cmd1_stdout ; cat "$tmpDir"/cmd1_stderr 1>&2; exit $(cat "$tmpDir"/cmd1_exitcode) )
A partir disso, podemos definir uma função "cache". Esta versão precisa de um personagem que nunca usaremos como argumento. Por exemplo, a vírgula ",". Você pode alterá-lo na linha "IFS =,"
tmpDir=/tmp/$$
rm -rf "$tmpDir"
mkdir "$tmpDir"
cache() {
IFS=, cmd="$*"
if [ -f "$tmpDir/$cmd"_exitcode ]; then
cat "$tmpDir/$cmd"_stdout
cat "$tmpDir/$cmd"_stderr 1>&2
return $(cat "$tmpDir"/cmd1_exitcode)
fi
# This line is bash-only:
"$@" 2> >(tee "$tmpDir/$cmd"_stderr 1>&2) > >(tee "$tmpDir/$cmd"_stdout)
local e=$?
echo $e > "$tmpDir/$cmd"_exitcode
return $e
}
O tempo limite pode ser implementado com "date +% s" e "stat -c% Y":
tmpDir=/tmp/$$
rm -rf "$tmpDir"
mkdir "$tmpDir"
cache() {
local timeout=$1
shift
IFS=, cmd="$*"
if [ -f "$tmpDir/$cmd"_exitcode ]; then
local now=$(date +%s)
local fdate=$(stat -c %Y "$tmpDir/$cmd"_exitcode)
if [ $((now-fdate)) -le $timeout ]; then
cat "$tmpDir/$cmd"_stdout
cat "$tmpDir/$cmd"_stderr 1>&2
return $(cat "$tmpDir/$cmd"_exitcode)
fi
fi
# This line is bash-only:
"$@" 2> >(tee "$tmpDir/$cmd"_stderr 1>&2) > >(tee "$tmpDir/$cmd"_stdout)
local e=$?
echo $e > "$tmpDir/$cmd"_exitcode
return $e
}
A linha "bash only" pode ser substituída por:
"$@" 2> "$tmpDir/$cmd"_stderr > "$tmpDir/$cmd"_stdout
local e=$?
cat "$tmpDir/$cmd"_stdout
cat "$tmpDir/$cmd"_stderr 1>&2