スクリプトは shebang "/usr/bin/env sh" では動作しませんが、sh は bash を指しますが、 "/usr/bin/env bash" では動作しません。

スクリプトは shebang

私は、最高のパフォーマンスを持つプログラムを選択するのに役立つ引数として渡されたさまざまなプログラムのパフォーマンスを記録するシェルスクリプトを持っています。関連スニペット:

#!/usr/bin/env sh
function cal_perf () {
        real_t=0
        user_t=0
        sys_t=0
        for (( trial=1 ; trial<=$3 ; ++trial )) ; do
                shopt -s lastpipe
                /usr/bin/time -f '%e:%S:%U' $1 $2 |& IFS=":" read real sys user
                real_t=$(echo "$real + $real_t" | bc)
                user_t=$(echo "$user + $user_t" | bc)
                sys_t=$(echo "$sys + $sys_t" | bc)
        done
        real_t=$(echo "scale=2 ; $real_t / $3" | bc)
        user_t=$(echo "scale=2 ; $user_t / $3" | bc)
        sys_t=$(echo "scale=2 ; $sys_t / $3" | bc)
        printf "%s\t%d\t%.2f\t%.2f\t%.2f\n" $2 $3 $real_t $user_t $sys_t >> timings_$(date '+%Y%m%d')
}

# main
printf "program\t#trials\treal_time_am\tuser_time_am\tsys time_am\n" > timings_$(date '+%Y%m%d')
translator=$1
shift
while [ $# -gt 1 ] ; do cal_perf $translator $1 ${!#} ; shift ; done

次のようにコマンドラインから実行する必要があります。

perf <translator_progam> <list_of_programs_to_compare> <number_of_trials>

xip.py, foo.py, bar.py, bas.py, qux.py...たとえば、作業ディレクトリの正味コンテンツパフォーマンスを比較し、統計を生成する前にこれを50回実行したいとします。

perf python *py 50

ここでは何か明白なものが欠けているようですが、このスクリプトを呼び出すと、すべてが期待bash $HOME/bin/perf ...どおりに機能します。ただし、次の2つの呼び出しは失敗します(追加のエラーを含む)。

  1. perf ...
  2. あるいは、作業ディレクトリに入れて、次のように呼び出すこともできます。./perf ...

ここに画像の説明を入力してください。

shebangを変更すると/usr/bin/env bash問題は解決しましたが、私のシステム/usr/bin/shで問題が発生しました。/usr/bin/bash

ベストアンサー1

shスクリプトをインタプリタとして実行していますが、関数を使用していますbash。それがそれを指していると仮定してもsh、実行するように要求されたときに多くのカスタム機能が無効になるbashため、まだこれを行うことはできません。bashsh

1つの解決策は、スクリプトを正しく宣言することです。bash関数を使用しているので、これをbashスクリプトとして宣言してください。

#!/bin/bash

envまたは継続して依存する必要がある場合

#!/usr/bin/env bash

別のオプションは、bash特定の構文を削除することです。

どちらの場合も、変数を使用するときに二重引用符で囲む必要があることを忘れないでください。たとえば、引用符のない変数(スクリプト引数を含む)の1つにスペースが含まれている場合、シェルはそれを2つ以上の単語に分割します。

おすすめ記事