.bash_profile
ipyを実行すると、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
変数に割り当てると、$PREV
nullにのみ割り当てられることがわかります。しかし、この問題は他の投稿で正式に取り上げます。私は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.log
prev
ipy.log