shell脚本中的变量插值

shell脚本中的变量插值

我为 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文件名一样。

相关内容