O código funciona manualmente no terminal, mas não pode executar o script

6

Eu criei este script para fazer backup do meu banco de dados postgresql com o cron:

backup.sh

#!/bin/bash
export PGUSER="user"
export PGPASSWORD="pass"
FECHA_ACTUAL='date +%Y-%m-%d'
HORA_ACTUAL='date +%H:%M'
ARCH_RESP=$FECHA_ACTUAL-$HORA_ACTUAL
pg_dump -O -Fc mydb -h localhost > /home/user/backups/backup_$ARCH_RESP.sql
find /home/user/backups/ -name '*.sql' -mtime +2 -exec rm -f {} \;
unset PGUSER
unset PGPASSWORD

Se eu copiar e colar esse código no terminal, ele funcionará bem, mas se eu tentar executar o script, recebo este erro:

user@dental:~/scripts$ ./backup.sh
export: bad interpreter: no such file or directory

Há algo errado com o meu script? Ou é o intérprete errado, como se diz?

    
por Elros Romeo 22.08.2016 / 14:15

1 resposta

11

Eu posso obter o mesmo erro se a primeira linha for terminada apenas com um CR (em vez de LF):

$ echo -en '#!/bin/bash\rexport foo=bar\n' > test.sh
$ chmod +x test.sh
$ ./test.sh
export: bad interpreter: No such file or directory

O que acontece é que o kernel procura por um programa de intérprete chamado /bin/bash\rexport , não o encontra e solta um erro. Bash imprime uma mensagem de erro com o nome do arquivo

bash: ./test.sh: /bin/bash\rexport: bad interpreter: No such file or directory

mas como o retorno do carro move a saída de volta para a frente da linha, você vê apenas

export: bad interpreter: No such file or directory

Então, o problema parece estar nos finais de linha.

Note que com uma terminação de linha CRLF no estilo DOS, o resultado é diferente, já que existe um LF para terminar a linha agora.

$ echo -en '#!/bin/bash\r\nexport foo=bar\n' > test.sh
$ ./test.sh    
bash: ./test.sh: /bin/bash^M: bad interpreter: No such file or directory

Embora eu não saiba porque o bash parece citar o CR na saída como ^M desta vez.

IIRC o CR solitário como fim de linha é um remanescente de sistemas Mac antigos e dos2unix não parece consertá-lo por padrão. Você precisaria usar mac2unix ou dos2unix -c mac .

Algo como isso também deve transformar todos os CR ou CRLF em finais de linha LF estilo Unix, se você tiver todos os estilos misturados e não precisar dos CRs em outro sentido.

sed 's/\r/\n/g;s/\n$//' backup.sh
    
por 22.08.2016 / 14:35