Un document en ligne utilise une forme spéciale de redirection d'E/S pour fournir une liste de commande à un programme ou une commande interactifs, tels que ftp, telnet ou ex. Une << chaîne de caractères délimite >> encadre la liste de commandes. Le symbôle spécial << désigne la chaîne de caractères de limite. Ceci a pour effet de rediriger la sortie d'un fichier vers le programme, de façon similaire à programme-interactif < fichier-commandes, où fichier-commandes contient
commande n°1 commande n°2 ... |
L'alternative au << document en ligne >> ressemble à ceci:
#!/bin/bash programme-interactif <<ChaineLimite commande #1 commande #2 ... ChaineLimite |
Choisissez une chaîne de caractères de limite suffisamment inhabituelle pour qu'elle ne soit pas présente où que ce soit dans la liste de commandes et qu'aucune confusion ne puisse arriver.
Notez que les documents en ligne peuvent parfois être utilisés correctement avec des utilitaires et des commandes non interactifs.
Exemple 17-1. fichierstupide: Crée un fichier stupide de deux lignes
#!/bin/bash # Utilisation non interactive de 'vi' pour éditer un fichier. # Emule 'sed'. E_MAUVAISARGS=65 if [ -z "$1" ] then echo "Usage: `basename $0` nomfichier" exit $E_MAUVAISARGS fi FICHIERCIBLE=$1 # Insère deux lignes dans le fichier et le sauvegarde. #--------Début document en ligne-----------# vi $FICHIERCIBLE <<x23LimitStringx23 i Ceci est la ligne 1 du fichier exemple. Ceci est la ligne 2 du fichier exemple. ^[ ZZ x23LimitStringx23 #--------Fin document en ligne-----------# # Notez que ^[ ci-dessus est un échappement littéral, tapé par #+ Control-V <Esc>. # Bram Moolenaar indique que ceci pourrait ne pas fonctionner avec 'vim', #+ dû à de possibles problèmes avec l'interaction du terminal. exit 0 |
Le script ci-dessus pourrait avoir été aussi efficacement implémenté avec ex, plutôt que vi. Les documents en ligne contenant une liste de commandes ex sont assez courant pour disposer de leur propre catégorie, connue sous le nom de scripts ex.
Exemple 17-2. broadcast: Envoie un message à chaque personne connectée
#!/bin/bash wall <<zzz23EndOfMessagezzz23 Envoyez par courrier électronique vos demandes de pizzas à votre administrateur système. (Ajoutez un euro supplémentaire pour les anchois et les champignons.) # Un message texte supplémentaire vient ici. # Note: Les lignes de commentaires sont affichées par 'wall'. zzz23EndOfMessagezzz23 # Peut se faire plus efficacement avec # wall <message-file # Néanmoins, sauvegardez un message modèle dans un script fonctionne. exit 0 |
Exemple 17-3. Message multi-lignes en utilisant cat
#!/bin/bash # 'echo' est bien pour afficher des messages sur une seule ligne, mais est # parfois problèmatique pour des blocs de message. # Un document en ligne style 'cat' permet de surpasser cette limitation. cat <<Fin-du-message ------------------------------------- Ceci est la ligne 1 du message. Ceci est la ligne 2 du message. Ceci est la ligne 3 du message. Ceci est la ligne 4 du message. Ceci est la dernière ligne du message. ------------------------------------- Fin-du-message exit 0 #-------------------------------------------- # Le code ci-dessous est désactivé, à cause du "exit 0" ci-dessus. # S.C. indique que ce qui suit fonctionne aussi. echo "------------------------------------- Ceci est la ligne 1 du message. Ceci est la ligne 2 du message. Ceci est la ligne 3 du message. Ceci est la ligne 4 du message. Ceci est la dernière ligne du message. -------------------------------------" # Néanmoins, le texte pourrait ne pas inclure les doubles guillemets sauf si #+ ils sont échappés. |
L'option - pour marquer la chaîne de caractères de limite d'un document en ligne (<<-ChaineLimite) supprime les tabulations (mais pas les espaces) lors de la sortie. Ceci est utile pour réaliser un script plus lisible.
Exemple 17-4. Message multi-lignes, aves les tabulations supprimées
#!/bin/bash # Identique à l'exemple précédent, mais... # L'option - pour un document en ligne <<- # supprime les tabulations dans le corps du document, mais *pas* les #+ espaces. cat <<-FINDUMESSAGE Ceci est la ligne 1 du message. Ceci est la ligne 2 du message. Ceci est la ligne 3 du message. Ceci est la ligne 4 du message. Ceci est la dernière ligne du message. FINDUMESSAGE # La sortie du script sera poussée. # Chaque tabulation sur chaque ligne ne s'affichera pas. # Les cinq lignes du "message" préfacées par une tabulation, et non des espaces, # Les espaces ne sont pas affectés par <<- . exit 0 |
Un document en ligne supporte la substitution de paramètres et de commandes. Il est donc possible de passer différents paramètres dans le corps du document en ligne, en changeant la sortie de façon appropriée.
Exemple 17-5. Document en ligne avec une substitution de paramètre
#!/bin/bash # Autre document en ligne 'cat', utilisant la substitution de paramètres. # Essayez-le sans arguments, ./scriptname # Essayez-le avec un argument, ./scriptname Mortimer # Essayez-le avec deux arguments entre guillemets, # ./scriptname "Mortimer Jones" CMDLINEPARAM=1 # Attendez au moins un paramètre en ligne de commande. if [ $# -ge $CMDLINEPARAM ] then NOM=$1 # Si plus d'un paramètre en ligne de commande, prendre # seulement le premier. else NOM="John Doe" # Par défaut, si il n'y a pas de paramètres. fi INTERLOCUTEUR="l'auteur de ce joli script" cat <<FinDuMessage Salut, $NOM. Bienvenue à toi, $NOM, de la part de $INTERLOCUTEUR. # Ce commentaire s'affiche dans la sortie (pourquoi?). FinDuMessage # Notez que les lignes blanches s'affichent. Ainsi que le commentaire. exit 0 |
Mettre entre guillemets ou échapper la << chaîne de caractères de limite >> au début du document here désactive la substitution de paramètres en son corps. Ceci a un intérêt très limité.
Exemple 17-6. Substitution de paramètres désactivée
#!/bin/bash # Un document en ligne 'cat', mais avec la substitution de paramètres #+ désactivée. NOM="John Doe" INTERLOCUTEUR="l'auteur de ce joli script" cat <<'FinDuMessage' Salut, $NOM. Bienvenue à toi, $NOM, de la part de $INTERLOCUTEUR. FinDuMessage # Pas de substitution de paramètres lorsque la chaîne de fin est entre #+ guillemets ou échappée. # L'une des deux commandes ci-dessous à l'entête du document en ligne aura le #+ le même effet. # cat <<"FinDuMessage" # cat <<\FinDuMessage exit 0 |
C'est un script utile contenant un document en ligne avec une substitution de paramètres.
Exemple 17-7. upload: Envoie un fichier vers le répertoire incoming chez << Sunsite >>
#!/bin/bash # upload.sh # Téléchargement de fichiers par pair (Fichier.lsm, Fichier.tar.gz) # pour le répertoire entrant de Sunsite (metalab.unc.edu). E_ERREURSARGS=65 if [ -z "$1" ] then echo "Usage: `basename $0` nomfichier" exit $E_ERREURSARGS fi NomFichier=`basename $1` # Supprime le chemin du nom du fichier. Serveur="metalab.unc.edu" Repertoire="/incoming/Linux" # Ils n'ont pas besoin d'être codés en dur dans le script, # mais peuvent être à la place changés avec un argument en ligne de commande. MotDePasse="votre.addresse.email" # A changer suivant vos besoins. ftp -n $Serveur <<Fin-De-Session # L'option -n désactive la connexion automatique user anonymous "$MotDePasse" binary bell # Sonne après chaque transfert de fichiers. cd $Repertoire put "$NomFichier.lsm" put "$NomFichier.tar.gz" bye Fin-De-Session exit 0 |
Un document en ligne peut donner une entrée à une fonction du même script.
Exemple 17-8. Documents en ligne et fonctions
#!/bin/bash # here-function.sh ObtientDonneesPersonnelles () { read prenom read nom read adresse read ville read etat read codepostal } # Ceci ressemble vraiment à une fonction interactive, mais... # Apporter l'entrée à la fonction ci-dessus. input to the above function. ObtientDonneesPersonnelles <<ENREG001 Bozo Bozeman 2726 Nondescript Dr. Baltimore MD 21226 RECORD001 echo echo "$prenom $nom" echo "$adresse" echo "$ville, $etat $codepostal" echo exit 0 |
Il est possible d'utiliser : comme commande inactive acceptant une sortie d'un document en ligne. Cela crée un document en ligne << anonyme >>.
Exemple 17-9. Document en ligne << Anonyme >>
#!/bin/bash : <<TESTVARIABLES ${HOSTNAME?}${USER?}${MAIL?} # Affiche un message d'erreur si une des variables n'est pas configurée. TESTVARIABLES exit 0 |
![]() | Une variante de la technique ci-dessus permet de << supprimer les commentaires >> de blocs de code. |
Exemple 17-10. Décommenter un bloc de code
#!/bin/bash # commentblock.sh : << BLOC_COMMENTAIRE echo "Cette ligne n'est pas un echo." C'est une ligne de commentaire sans le préfixe "#". Ceci est une autre ligne sans le préfixe "#". &*@!!++= La ligne ci-dessus ne causera aucun message d'erreur, Parce que l'interpréteur Bash l'ignorera. BLOC_COMMENTAIRE echo "La valeur de sortie du \"BLOC_COMMENTAIRE\" ci-dessus est $?." # 0 # Pas d'erreur. # La technique ici-dessus est aussi utile pour mettre en commentaire un bloc #+ de code fonctionnel pour des raisons de déboguage. # Ceci permet d'éviter de placer un "#" au début de chaque ligne, et d'avoir #+ ensuite à les supprimer. : << DEBUGXXX for fichier in * do cat "$fichier" done DEBUGXXX exit 0 |
![]() | Encore une autre variante de cette symmpathique astuce rendant les scripts << auto-documentés >> possibles. |
Exemple 17-11. Un script auto-documenté
#!/bin/bash # self-document.sh: script auto-documenté # Modification de "colm.sh". DEMANDE_DOC=70 if [ "$1" = "-h" -o "$1" = "--help" ] # Demande de l'aide. then echo; echo "Usage: $0 [nom-repertoire]"; echo cat "$0" | sed --silent -e '/DOCUMENTATIONXX$/,/^DOCUMENTATION/p' | sed -e '/DOCUMENTATIONXX/d'; exit $DEMANDE_DOC; fi : << DOCUMENTATIONXX Liste les statistiques d'un répertoire spécifié dans un format de tabulations. ------------------------------------------------------------------------------ Le paramètre en ligne de commande donne le répertoire à lister. Si aucun répertoire n'est spécifié ou que le répertoire spécifié ne peut être lu, alors listez le répertoire courant. DOCUMENTATIONXX if [ -z "$1" -o ! -r "$1" ] then repertoire=. else repertoire="$1" fi echo "Liste de "$repertoire":"; echo (printf "PERMISSIONS LIENS PROP GROUPE TAILLE MOIS JOUR HH:MM NOM-PROG\n" \ ; ls -l "$repertoire" | sed 1d) | column -t exit 0 |
![]() | Les documents en ligne créent des fichiers temporaires, mais ces fichiers sont supprimés après avoir été ouvert et ne sont plus accessibles par aucun autre processus.
|
![]() | Quelques utilitaires ne fonctionneront pas à l'intérieur d'un document en ligne. |
Pour ces tâches trop complexes pour un << document en ligne >>, considérez l'utilisation du langage de scripts expect, qui est conçu spécifiquement pour alimenter l'entrée de programmes interactifs.
Précédent | Sommaire | Suivant |
Applications | Niveau supérieur | Récréation |