すべてのコマンドを覚えるために、次の関数を作成しました。
# zsh
(( $+functions[ec] )) || {
ec() print -r -- "$@"
ecerr() { ec "$@" 1>&2 }
ecdbg() ecerr "$@"
gq() { ec "${(q+@)@}" }
}
(( $+functions[dvar] )) || function dvar() {
local pre=''
test -z "$2" || pre="CODE $2 | "
echo "$pre$(typeset -p "$1" 2>&1)"
echo "$pre$1 in env: $(printenv "$1")"
}
## Aliases
## Vars
memoi_expire=$(( 3600*24*7 ))
## Functions
function mem() { memoi_expire=$(( $1 * 60 )) reval "$@" }
function memoi-eval() {
typeset -Ag memoi_stdout
typeset -Ag memoi_stderr
typeset -Ag memoi_timestamp
typeset -Ag memoi_exit
typeset -Ag memoi_debug
dvar memoi_exit
local now="$(date +%s)"
local cmd="$(gq "$@")"
re dvar cmd memoi_expire memoi_timestamp now
{ (( $+memoi_timestamp[$cmd] )) && ecdbg ice0 && { (( memoi_expire == 0 )) || { ((memoi_expire >= 0 )) && ecdbg fire0 && (( (now - memoi_timestamp[$cmd]) <= memoi_expire )) && ecdbg fire1 } } && ecdbg monkey0 } && {
dact fsay using memoi
ecdbg Using memoi: "$cmd"
test -n "$memoi_stdout[$cmd]" && ec "$memoi_stdout[$cmd]"
test -n "$memoi_stderr[$cmd]" && ecerr "$memoi_stderr[$cmd]"
(exit 0)
} || {
dact fsay memoi not fresh enough
ecdbg 'Evaling (no memoi): ' "$cmd"
local errfile="$(mktemp)"
memoi_stdout[$cmd]="$(eval "$cmd" 2>"$errfile")"
memoi_exit[$cmd]=$?
memoi_stderr[$cmd]="$(<$errfile)"
\rm "$errfile"
memoi_timestamp[$cmd]="$(date +%s)"
test -n "$memoi_stdout[$cmd]" && ec "$memoi_stdout[$cmd]"
test -n "$memoi_stderr[$cmd]" && ecerr "$memoi_stderr[$cmd]"
}
dvar memoi_exit
# dvar memoi_stdout
memoi_debug[$cmd]=yes
memoi_debug[apple]=yes
return $memoi_exit[$cmd]
}
しかし、私の問題は、シェルがフォークでいっぱいで、フォークされたサブシェルが親シェルの変数を設定できないことです。したがって、
memoi-eval echo hi
有効ですが
memoi-eval echo hi2 |cat
いいえ。私のオプションは何ですか?
プロセス置換の次の回避策が見つかりました(一部の空白が失われました)。
local some_var
nulterm some_command |read -d '' -r some_var
# deps
reval () {
ecdbg revaling "$(gq "$@")"
eval "$(gq "$@")"
}
nulterm () {
reval "$@"
ec $'\0'
}
しかし、パイプを避けることはかなり難しいです。これを行うための優雅な方法はありますか? sを使用すると効果があるようですが、fifo
コーディングが非常に難しくなります。
メモリ内のKey-Valueストアを使用する必要がありますかredis
?