シェルスクリプトの変数補間

シェルスクリプトの変数補間

私はpgバックアップのために次のシェルスクリプトを書いた。

#!/bin/bash

PG_USER=donato
DATABASE=mydb
SERVER=216.58.219.174
DIR="$HOME/pg_bak"
DATE=$(date +"%m_%d_%y")
FILE="$DATABASE_$DATE"
ERROR_FILE="$HOME/pg_bak/error_bak/$FILE_error.txt"
# pass @ .pgpass

PG_BAK_NOW () {
  pg_dump -h $SERVER -U $PG_USER $DATABASE >$FILE 2>$ERROR_FILE
  code=$?
  if [ $code -ne 0 ]; then
    echo 1>&2 "The backup failed (exit code $code), check for errors in $ERROR_FILE"
  fi
}

echo "Ready to dump to $FILE" >> "$HOME/pg_status" 

cd $DIR
if [ -f "$FILE" ];
then
  rm $FILE
  PG_BAK_NOW 
else
  PG_BAK_NOW
fi

実行すると、しばらく実行されることがわかります。

$ pgrep -fl pg_bak.sh
4603 pg_bak.sh

しかし、競合が発生します。

$ ./pg_bak.sh
The backup failed (exit code 1), check for errors in /home/viggy/pg_bak/error_bak/.txt

この部分に注意してください.txt。エラーファイルの名前mydb_6_11_2016_error.txtではないはずです.txt。 bashスクリプトが$ FILE変数とハードコードされた文字列 "_error"を挿入しないのはなぜですか?ダンプファイルには$ FILEを正しく挿入しますが、エラーファイルには挿入しません。なぜ?

答え1

非常に一般的な間違いです。中かっこがありません。

ERROR_FILE="$HOME/pg_bak/error_bak/$FILE_error.txt"

次の式によって決定されます。

ERROR_FILE="$HOME/pg_bak/error_bak/${FILE}_error.txt"

答え2

jlliagreが指摘したように、bashが変数名として扱う文字列部分の周りに中括弧を使用する必要があります。それ以外の場合は、名前の一部になることができない文字に達すると、文字列を名前として処理するのを停止します。

この場合、FILE_error変数名は_変数名で許可されているように処理されます。実際にはその部分だけが必要なので、FILEその部分の周りに中かっこを入れて明示的にbashに知らせなければなりません${FILE}_error

あなたの例では設定されていないので空の文字列に展開されるので、取得する内容はファイル名FILE_errorと同じです。.txt

関連情報