我为 pg 备份编写了以下 shell 脚本:
#!/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
文件名一样。