variável de interpolação no shell script

3

Eu escrevi o seguinte script de shell para um backup de 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

Quando eu o executo, sei que ele é executado por um tempo:

$ pgrep -fl pg_bak.sh
4603 pg_bak.sh

Mas, em seguida, ele falha:

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

Observe a parte .txt . O nome do arquivo de erro deveria ser mydb_6_11_2016_error.txt , não .txt . Por que o script bash não interpolou a variável $ FILE e a string "_error" codificada? Ele interpola $ FILE no arquivo de despejo corretamente, mas não no arquivo de erro. Por quê?

    
por Donato 12.06.2016 / 01:41

2 respostas

5

Um erro muito comum:

ERROR_FILE="$HOME/pg_bak/error_bak/${FILE}_error.txt"
    
por 12.06.2016 / 01:44
2

Como jlliagre apontou, você precisa usar chaves ao redor da parte da string que você deseja que o bash trate como um nome de variável. Caso contrário, ele só deixará de tratar a string como o nome quando chegar a um personagem que não possa fazer parte do nome.

Nesse caso, FILE_error está sendo tratado como o nome da variável porque _ é permitido em nomes de variáveis. Você realmente quer apenas a parte FILE , então você precisa dizer ao bash que especificamente colocando chaves em torno dessa parte como ${FILE}_error .

No seu exemplo FILE_error nunca foi definido, então ele se expande para uma string vazia, então você tem apenas .txt como o nome do arquivo.

    
por 12.06.2016 / 01:50