if文を使用して変数を呼び出すと、-bash: 'Command not find'が発生します。

if文を使用して変数を呼び出すと、-bash: 'Command not find'が発生します。

.bash_profileipyを実行すると、7日以上ごとにログファイルが消去されるようにファイルを変更しています。問題は、if文で変数を参照するたびにreturnが返されることです-bash: command not found

  1 #!/bin/sh
  2 # .bash_profile
  ...
 15 # These lines clear the ipy.log every seven or more days
 16 PREV=$(awk '/./{line=$0} END{print line}' days.log)
 17 echo $PREV
 18 WEEKDAY=$(date '+%Y%m%d')
 19 echo $WEEKDAY
 20 DIF=$((WEEKDAY-PREV))
 21 MARKER=false
 22 if [ ${DIF} > 6 ]; then
 23     YEAR=$(date '+%Y')
 24     MON=$(date '+%m')
 25     DAY=$(date '+%d')
 26     DIGIT=${DAY:-1}
 27     if [ ${DIGIT} -eq 1 ]; then
 28         TAG='st'
 29     elif [ ${DIGIT} -eq 2 ]; then
 30         TAG='nd'
 31     elif [ ${DIGIT} -eq 3 ]; then
 32         TAG='rd'
 33     else
 34         TAG='th'
 35     fi
 36     TIMESTAMP=$(date '+%H:%M:%S')
 37     MARKER=true
 38     PRINT=$("ipy.log was cleared at ${TIMESTAMP} on ${WEEKDAY} the ${DAY}${TAG}  of  ${MON},  ${YEAR}")
 39     echo ${PRINT}
 40     ${PRINT} > ~/ipy.log
 41     ${WEEKDAY} > ~/days.log
 42 else
 43     echo "It has been ${DIF} days since your last write, no need to clear logs"
 44 fi

出力:


20200216
-bash: ipy.log was cleared at 14:35:45 on 20200216 the 16th  of  02,  2020: command not found

-bash: 20200216: command not found

ファイルの最後の行を呼び出してdays.log変数に割り当てると、$PREVnullにのみ割り当てられることがわかります。しかし、この問題は他の投稿で正式に取り上げます。私はcommand not foundこれらのステートメントがどのようになぜ行われたのかを知りたいと思います。

答え1

15行目では、次の操作を行います。

WEEKDAY=$(date '+%Y%m%d')

したがって、WEEKDAY == "20200216"またはそれに似ています。 41行目では、次の操作を行います。

${WEEKDAY} > ~/days.log

${WEEKDAY}「20200216」に置き換えられます。 Bashが提供する最初の文字列は常にコマンドです(キーワード、割り当て、その他の項目は除外しますが、今は忘れてください)。したがって、bash以下を実行しようとします。

20200216

これは存在しません。次のように書きたい場合があります。

echo "${WEEKDAY}" > ~/days.log

代わりに。

答え2

20行目「DIF=$((WEEKDAY-PREV))」で算術を使用しているので、22行目で読むのが最善の方法だと思います。

22 if [ ${DIF} -gt 6 ]; then

また、前にTomáš Pospíšekが述べたように、40行と41行では変数の前にコマンドが必要であるため、次のことを読む必要があります。

40 echo "${PRINT}" > ~/ipy.log
41 echo "${WEEKDAY}" > ~/days.log

答え3

次の行は意味がありません。

PRINT=$("ipy.log was cleared at ${TIMESTAMP} on ${WEEKDAY} the ${DAY}${TAG}  of  ${MON},  ${YEAR}")

文法$(...)注文する交換されたので、bash以下を実行してみてください。

ipy.log was cleared at ${TIMESTAMP} on ${WEEKDAY} the ${DAY}${TAG}  of  ${MON},  ${YEAR}

コマンドで。

代わりに、次のことができます。

  • 変数をPRINT文字列に設定します。
PRINT="ipy.log was cleared at ${TIMESTAMP} on ${WEEKDAY} the ${DAY}${TAG}  of  ${MON},  ${YEAR}"
  • echo端末の文字列:
echo "$PRINT"
  • echoファイルの文字列:
echo "$PRINT" > ~/ipy.log

ファイルはすでに存在しますが、次のエラーのために空であるため、ファイルの割り当てはPREV期待どおりに機能しません。~/days.log

${WEEKDAY} > ~/days.log

これはおそらく次のとおりです。

echo "$WEEKDAY" > ~/days.log

以下は少し異なるアプローチです。

# This function clears ipy.log every seven or more days
function clear_ipylog() {
    typeset -i prev yearmday dif
    typeset tag timedate message
    typeset -g marker
#     read -r prev <"$HOME/days.log" # Should work instead of awk as days.log should only contain '%Y%m%d'
    prev=$(awk '/./{line=$0} END{print line}' "$HOME/days.log")
    echo $prev >&2
    yearmday=$(date '+%Y%m%d')
    echo $yearmday >&2
    dif=$((yearmday-prev))
    if [ $dif -gt 6 ]; then
        case ${yearmday:6:2} in
            (01) tag='st' ;;
            (02) tag='nd' ;;
            (03) tag='rd' ;;
            (*) tag='th' ;;
        esac
        timedate=$(date '+%H:%M:%S %F%b')
        message=$(printf '%s %d%s\n' "ipy.log was cleared at ${timedate:0:19}, the" \
            "${yearmday:6:2}" "$tag of ${timedate:19} ${yearmday:0:4}")
        echo "$message" > "$HOME/ipy.log"
        echo "$message" >&2
        echo $yearmday > "$HOME/days.log"
        marker='true'
    else
        echo "It has been $dif days since your last write, no need to clear logs"
        marker='false'
    fi
}
clear_ipylog
  • これは関数内でいくつかの変数を分離することです。などをグローバル変数に設定したくないとします$prev$dif
  • それが何であるかわからないので、$markerグローバル変数に設定するとします。
  • ~/.bash_profile~/.bashrc直接読み取るbashので、この行から始めたり、#!/bin/sh実行モードを設定したりしないでください。
  • 最初の行/フィールドからインポートできるように、~/days.log最初の行の形式を変更して廃止することを検討できます。~/ipy.logprevipy.log

関連情報