Um erro muito comum:
ERROR_FILE="$HOME/pg_bak/error_bak/${FILE}_error.txt"
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ê?
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.
Tags bash shell-script