zshスクリプトをzshシェル関数に変換する

zshスクリプトをzshシェル関数に変換する

使っていますzshで独自のシェル関数を定義してロードする方法私のzshスクリプトをシェル関数に変換します。

これスクリプト私が変換したいのは次のとおりです。

#! /bin/zsh -

trap true INT QUIT

zmodload zsh/datetime
TIMEFMT='Total duration: %*E'
strftime -s start 'Start Time: %d/%m/%y %I:%M%P'
{
  duration=$(
    exec 4>&2 2>&1 1>&3 3>&-
    time "$@" 2>&4 4>&-
  )
} 3>&1
ret=$?
strftime -s end 'End Time: %d/%m/%y %I:%M%P'
echo -e
print -rlu2 $start $end $duration
return $ret

だから私はshebangを削除し、スクリプトを私のfpath

問題はもう表示されないことです$duration

% reporttime tail -f ~/.xsession-errors
Cinnamon warning: Log level 128: posix_spawn avoided (fd close requested)
Cinnamon warning: Log level 128: posix_spawn avoided (fd close requested)
Cinnamon warning: Log level 128: posix_spawn avoided (fd close requested)
Cinnamon warning: Log level 128: posix_spawn avoided (fd close requested)
Cinnamon warning: Log level 128: posix_spawn avoided (fd close requested)
Cinnamon warning: Log level 128: posix_spawn avoided (fd close requested)
^C
Start Time: 03/01/21 03:15pm
End Time: 03/01/21 03:15pm

どうですか?

答え1

問題を再現できません。ただし、自動ロード可能な関数にするには、トラップと変数を関数にローカルに作成する必要があります。の出力は、echo -eレポートの残りの部分と同様にstderrに送信するか、呼び出しに改行を追加する必要がありますprint

zmodload zsh/datetime

set -o localtraps
trap true INT QUIT

local TIMEFMT='Total duration: %*E' start end ret duration

strftime -s start 'Start Time: %d/%m/%y %I:%M%P'

{
  duration=$(
    exec 4>&2 2>&1 1>&3 3>&-
    time "$@" 2>&4 4>&-
  )
} 3>&1
ret=$?

strftime -s end 'End Time: %d/%m/%y %I:%M%P'
print -rlu2 '' $start $end $duration
return $ret

別のオプションは、全体をラップしてサブシェル(...)で実行することです。

前述の回答ですでに述べたように、プロセスによって消費されたリソースを報告するので(経過時間とCPU時間に限定されず、zshメモリ使用量、コンテキスト切り替え、I / O操作も含まれる可能性があります)、サブプロセスで実行されるコマンドのみ使用できます。したがって、関数を使用するには、その関数がサブシェルプロセスで実行されるようにwithに置き換える必要があります。timezshtimetime "$@"time ("$@")

しかし、あなたは興味だけに興味があるので過去実際にリソースを処理する代わりに、私が提案した他のアプローチを使用して終了時間を手動で計算することもできます(必要に応じて手動でフォーマットまたは使用することもできますHH:MM:SS.TTT)。strftime

関連情報