プロトタイプを作成する必要があるいくつかのアルゴリズムがあります。
だからプロトタイプとスクリプトを作成しました。呼び出されるスクリプトはtime.sh
次のとおりです。
echo "Timing algorithm1:"
time algo1 >dev/null
echo "Timing algorithm2:"
time algo2 >dev/null
echo "Timing algorithm3:"
time algo3 >dev/null
...
さて、単純化のために...ls
に置き換えてくださいalgo1
。 (すべてのアルゴリズムのコードを公開し、人々にそれらをコンパイルするよう強制したくありません...)
echo " Timing ls"
time ls 2>&1 > /dev/null
呼ぶtime_ls.sh
それから私は
sh time_ls.sh > ls_sh.meas
私が何をしても、スクリプトやコマンドラインにどのリダイレクトを入力しても、2つの結果のいずれかを取得します。ターミナルから「Timing ls」というエコー出力を取得するか、ls_sh.meas
反対のタイミングデータを取得します。
これは、stdoutとstderrが一緒に集まり、赤ちゃんのデータファイルを生成したくないようです。
誰でもこの奇妙な動作を説明し、回避策を提案できますか?
PS:これはbashで行われます。
答え1
Kornのようなシェルには、以下をtime
紹介するキーワードがあります。
time <pipeline>
構造。time
パイプの時はパイプで連結された命令である。
time for i in 1 2; do
echo "$i"
done 2>&1 | {
read a
read b
ls /etc /x
} 2> /dev/null
time ls 2>&1
タイムアウトパイプラインの例ですtime
。
time
パイプラインのプロセスが返された後、統計はシェルのstderrに報告されますが、パイプラインの各タイミング部分の間に統計出力を2> ...
リダイレクトしません。time
リダイレクトするにはstderrが必要です。今後構成をtime ...
評価します。たとえば、
{ time <pipeline>; } 2> ...
eval 'time <pipeline>' 2> ...
exec 2> ...; time <pipeline>
time
問題のコマンドエラーではなく出力のみをリダイレクトするには、古い<pipeline>
標準エラーを別の標準エラーに保存fd
し、クロック中のパイプから復元できます。たとえば、
{
time {
<pipeline>
} 2>&3 3>&-
} 3>&2 2> ...
この出力を別のコマンドにパイプします。
{
{
time {
<pipeline>
} 2>&3 3>&-
} 3>&2 2>&1 >&4 4>&- | another command 4>&-
} 4>&-
fd 4に保存した後、標準出力も復元する必要があります。
すべてのstdout、stderr、およびtime
統計をコマンドに渡すには、次のようにします。
{ time <pipeline>; } 2>&1 | a command
答え2
time
同じログファイルに各プロトタイプの出力と出力を含めたいと思います。
#!/bin/bash
# Name as "algon1" (
echo "Timing algorithm1:"
time algo1 >/dev/null
echo "Timing algorithm2:"
time algo2 >/dev/null
echo "Timing algorithm3:"
time algo3 >/dev/null
) > algon1.log 2>&1
次に、ファイルを実行可能にして呼び出します。
chmod a+x algon1
./algon1
または、出力ファイル名をスクリプトにハードコードしない場合は、代わりに出力標準出力:
#!/bin/bash
# Name as "algon2"
(
echo "Timing algorithm1:"
time algo1 >/dev/null
echo "Timing algorithm2:"
time algo2 >/dev/null
echo "Timing algorithm3:"
time algo3 >/dev/null
) 2>&1
そして
chmod a+x algon2
./algon2 | tee algon2.log
両方のスクリプトでアルゴリズム出力にタイミングが含まれるようにするには、各行>/dev/null
からそれらを削除できます。time
答え3
スクリプトの先頭でリダイレクトを定義します。
#!/bin/bash
exec 2>&1
echo Timing ls 1
time ls &>/dev/null
echo Timing ls 2
time ls /jabberwocks &>/dev/null
./time_ls.sh > ls_sh.meas