Ainsi un script bash devrait avoir une première ligne du genre:
#!/bin/bash
Problème avec les scripts interprétés par psql: pour SQL, # n'indique pas un commentaire, mais bien --
Faisons le test dans un terminal psql:
Nous imprimons (\p) ce qui sera envoyé au serveur pour exécution avant de procéder (;). Nous constatons que le commentaire a disparu et n'est pas envoyé au serveur.
Par contre:
'# commentaire' figure bien dans ce qui est envoyé au serveur, d'où l'erreur.
Nous avons le même genre d'erreur lors de l'exécution du script sbpsql1x:
#!/usr/bin/psql -f
select now()
\echo 'Sera envoyé au serveur:'
\echo
\p
\echo
\echo 'Procédons:'
\echo
;
Vérifions:
Comme proposé ici on peut remplacer la ligne shebang par
--() { :; }; exec psql [options] -f "$0"
Notre script devient sbpsql2x:
--() { :; }; exec psql bdtest -f "$0"
select now()
\echo 'Sera envoyé au serveur:'
\echo
\p
\echo
\echo 'Procédons:'
\echo
;
Cette fois ça fonctionne car la ligne 1 est traitée comme un commentaire par psql:
Cette ligne n'est pas vraiment un shebang (où est #! ?). Elle commence par la définition d'une fonction (notée --) associée à une commande qui ne fait rien (:). Comme la fonction n'est jamais utilisée on pourrait mettre n'importe quoi (par exemple echo 'Hello') à la place de :).
En toute rigueur on devrait commencer le script par un véritable shebang, comme ceci:
#!/bin/bash
--() { :; }; exec psql bdtest -f "$0"
select now()
...
Mais on retombe alors sur la même erreur.
Une autre possibilité est celle utilisée dans ce script (sbpsql3x):
#!/bin/sh
exec sh -c "tail -n +3 $0 | psql bdtest -f -"
select now()
\echo 'Sera envoyé au serveur:'
\echo
\p
\echo
\echo 'Procédons:'
\echo
;
La commande tail envoie à partir de la ligne 3 le contenu du script (dont le nom se trouve dans $0) vers la commande psql. L'option -f - signifie que psql lit les instructions depuis l'entrée standard qui dans notre cas est la sortie standard de tail (voir ici: les canaux de communication avant et après un pipe: stdout de la commande en aval est connecté à stdin de la commande en amont).