Code funktioniert manuell auf dem Terminal, kann jedoch kein Skript ausführen

7

Ich habe dieses Skript erstellt, um meine Postgresql-Datenbank mit cron zu sichern:

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

Wenn ich diesen Code kopiere und auf dem Terminal einfüge, funktioniert er einwandfrei. Wenn ich jedoch versuche, das Skript auszuführen, wird folgende Fehlermeldung angezeigt:

user @ dental: ~ / scripts $ ./backup.sh
export: fehlerhafter Interpreter: keine solche Datei oder kein solches Verzeichnis

Stimmt etwas mit meinem Skript nicht? Oder ist es der falsche Dolmetscher, wie es heißt?

Elros Romeo
quelle
1
Was ist die Ausgabe von type -a bash?
Heemayl
Bitte bearbeiten Sie die Frage und veröffentlichen Sie die Ausgabe dieses Befehls : head -n 1 backup.sh | od -c.
Terdon
1
Ihre Datei ist wahrscheinlich nicht im Linux-Format. Wenn die Ausgabe von [Datei <Ihre-Datei>] "ASCII-Text mit CRLF-Zeilenabschlusszeichen" enthält, ändern Sie das Format mit dos2unix.
Tonioc

Antworten:

11

Ich kann den gleichen Fehler erhalten, wenn die erste Zeile nur mit einem CR (anstelle von LF) beendet wird:

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

Was passiert ist, dass der Kernel nach einem Interpreter-Programm namens sucht /bin/bash\rexport, es nicht findet und einen Fehler löscht. Bash druckt eine Fehlermeldung mit dem Namen der Datei

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

Da der Wagenrücklauf den Ausgang jedoch wieder an den Anfang der Zeile verschiebt, sehen Sie nur

export: bad interpreter: No such file or directory

Das Problem scheint also bei den Zeilenenden zu liegen.

Beachten Sie, dass bei einem CRLF-Zeilenende im DOS-Stil das Ergebnis anders ist, da jetzt ein LF zum Beenden der Zeile vorhanden ist.

$ 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

Obwohl ich nicht weiß, warum bash ^Mdiesmal die CR bei der Ausgabe zu zitieren scheint .


IIRC, die einzige CR als Zeilenende, ist ein Überbleibsel alter Mac-Systeme und dos2unixscheint dies nicht standardmäßig zu beheben. Sie müssten mac2unixoder verwenden dos2unix -c mac.

So etwas sollte auch alle CR- oder CRLF-Linien in Lix-Zeilenenden im Unix-Stil umwandeln, wenn Sie zufällig alle Stile verwechselt haben und die CRs in keinem anderen Sinne benötigen.

sed 's/\r/\n/g;s/\n$//' backup.sh
ilkkachu
quelle
Danke, es hat mit dem sed 's / \ r / \ n / g; s / \ n $ //' backup.sh funktioniert
Elros Romeo
Was habe ich falsch gemacht, als ich mein sh erstellt habe?
Elros Romeo
@ElrosRomeo Das ist schwerer zu sagen, da wir nicht wissen, wie Sie es erstellt haben. Einige Editoren können den Zeilenendstil auswählen, sodass es sich möglicherweise nur um eine Fehlkonfiguration im Editor handelt.
Ilkkachu
Danke, ich habe es mit mousepad geschrieben und mit der Erweiterung sh gespeichert, dann habe ich die Datei mit 777
Elros Romeo