
Salut, habrozhiteli! L'invite de commandes Linux, le best-seller international, vous aidera à surmonter le chemin depuis les premiers clics timides sur les clés jusqu'à la création sûre de programmes complets pour la dernière version de bash - le shell Linux le plus populaire. La deuxième édition aborde les nouvelles fonctionnalités de bash 4.x, telles que les nouveaux opérateurs de redirection et les opérations génériques. Vous apprendrez les compétences intemporelles de la ligne de commande: navigation dans le système de fichiers, configuration de l'environnement, chaînage des commandes et correspondance avec des expressions régulières. Vous comprendrez la philosophie de nombreux outils en ligne de commande, comprendrez le riche héritage des superordinateurs d'Unix et découvrirez les connaissances accumulées par des générations de gourous qui ont exclu la souris de leur arsenal d'outils. Après avoir surmonté le premier «choc de la coque», vous comprendrez à quel point cette façon d'interagir avec un ordinateur est naturelle et logique.
Extrait. Chapitre 25. Début du projet
Dans ce chapitre, nous commençons à créer le programme. Le but de ce projet est de montrer comment vous pouvez utiliser les différentes capacités du shell pour créer des programmes et, surtout, pour créer de
bons programmes.
Ensuite, nous allons écrire
un générateur de rapports . Il affichera une variété d'informations sur le système et son état au format HTML, afin qu'il puisse être consulté dans un navigateur Web.
En règle générale, la création de programmes s'effectue en plusieurs étapes, à chacune desquelles de nouvelles fonctions et capacités sont ajoutées. À la fin de la première étape, notre programme jouera une page HTML minimale sans aucune information. Nous ajouterons ces informations dans les prochaines étapes.
Première étape: document minimum
Tout d'abord, déterminons à quoi ressemble le format d'un document HTML bien formé. Il a la forme suivante:
<html> <head> <title> </title> </head> <body> . </body> </html>
Si vous entrez ce texte dans un éditeur de texte et l'enregistrez dans un fichier appelé
foo.html , nous pouvons l'ouvrir en saisissant l'URL suivante dans Firefox:
file: ///home/username/foo.html .
À la première étape, nous créerons un programme qui générera ce balisage HTML en sortie standard. L'écriture d'un tel programme est très simple. Ouvrez un éditeur de texte et créez un fichier appelé ~ / bin / sys_info_page:
[me@linuxbox ~]$ vim ~/bin/sys_info_page
Et puis entrez dans le programme suivant:
#!/bin/bash # echo "<html>" echo " <head>" echo " <title>Page Title</title>" echo " </head>" echo " <body>" echo " Page body." echo " </body>" echo "</html>"
Notre première version contient une ligne shebang, un commentaire (bienvenue) et une séquence de commandes d'écho, une pour chaque sortie de ligne. Après avoir enregistré le fichier, rendez-le exécutable et essayez d'exécuter:
[me@linuxbox ~]$ chmod 755 ~/bin/sys_info_page [me@linuxbox ~]$ sys_info_page
Après le démarrage, le texte du document HTML doit apparaître à l'écran, car les commandes d'écho du script envoient leurs lignes vers la sortie standard. Exécutez à nouveau le programme et redirigez la sortie du programme vers le fichier
sys_info_page.html , puis affichez le résultat dans un navigateur Web:
[me@linuxbox ~]$ sys_info_page > sys_info_page.html [me@linuxbox ~]$ firefox sys_info_page.html
Jusqu'à présent, tout va bien.
Lors du développement de programmes, vous devez toujours vous souvenir de la simplicité et de la clarté. La maintenance est plus facile lorsque le programme est facile à lire et compréhensible, sans parler du fait que le programme est plus facile à écrire lorsqu'il est possible de réduire la quantité de saisie manuelle. La version actuelle du programme fonctionne très bien, mais elle peut être simplifiée. La combinaison de toutes les commandes d'écho en une seule facilitera certainement à l'avenir l'ajout de nouvelles lignes à la sortie du programme. Par conséquent, nous modifions le programme comme indiqué ci-dessous:
#!/bin/bash # echo "<html> <head> <title>Page Title</title> </head> <body> Page body. </body> </HTML>"
Les chaînes entre guillemets peuvent inclure des sauts de ligne et, par conséquent, contenir plusieurs lignes de texte. Le shell continuera de lire le texte jusqu'à ce qu'il rencontre une citation de fermeture. Cette règle s'applique également sur la ligne de commande:
[me@linuxbox ~]$ echo "<html> > <head> > <title>Page Title</title> > </head> > <body> > Page body. > </body> > </html>"
Le symbole> au début de chaque ligne est une invite à entrer un shell défini par sa variable PS2. Il apparaît chaque fois qu'une instruction multiligne est entrée. Cette fonctionnalité est encore obscure, mais lorsque nous nous familiariserons avec les instructions du programme multiligne, ses avantages deviendront évidents.
Deuxième étape: ajouter des données
Maintenant que le programme est capable de générer un document minimal, ajoutez des données au rapport. Pour ce faire, apportez les modifications suivantes:
#!/bin/bash # echo "<html> <head> <title>System Information Report</title> </head> <body> <h1>System Information Report</h1> </body> </html>"
Ici est ajouté le nom de la page et le titre dans le corps du rapport.
Variables et constantes
Il y avait un problème dans notre script. Avez-vous remarqué que la ligne de rapport d'informations système est répétée deux fois? En général, pour un si petit scénario, ce n'est pas un gros problème, mais imaginez un scénario très long dans lequel cette ligne est répétée plusieurs fois. Si vous devez changer le nom dans un tel scénario, vous devrez apporter des modifications à de nombreux endroits, et cela demande beaucoup de travail manuel. Est-il possible de changer le script pour que la chaîne n'y soit définie qu'une seule fois? Cela simplifierait considérablement la maintenance du script à l'avenir. Oui, c'est possible, par exemple, comme ceci:
#!/bin/bash # title="System Information Report" echo "<html> <head> <title>$title</title> </head> <body> <h1>$title</h1> </body> </html>"
En créant une
variable appelée title et en lui affectant la valeur System Information Report, nous avons profité de la substitution de paramètres et placé la chaîne à de nombreux endroits.
Mais comment créer une variable? Simple - utilisez-le. Lorsque le shell rencontre une variable, il la crée automatiquement. Cela diffère de nombreux langages de programmation dans lesquels les variables doivent être explicitement déclarées ou définies avant d'être utilisées. L'enveloppe de commande est trop libérale à cet égard, ce qui conduit finalement à certains problèmes. Par exemple, considérez le script suivant exécuté sur la ligne de commande:
[me@linuxbox ~]$ foo="yes" [me@linuxbox ~]$ echo $foo yes [me@linuxbox ~]$ echo $fool [me@linuxbox ~]$
Nous avons d'abord attribué la valeur yes à la variable foo, puis la sortie de sa valeur avec la commande echo. Ensuite, nous avons essayé à nouveau d'afficher la valeur de la variable, mais nous avons fait une faute de frappe en spécifiant le nom fou, et nous avons obtenu une chaîne vide. Ce résultat s'explique par le fait que le shell a réussi à créer la variable fool lors de sa rencontre et lui a attribué une valeur par défaut vide. De cet exemple, il s'ensuit que vous devez surveiller attentivement l'orthographe! Il est également important de comprendre ce qui s'est réellement passé dans cet exemple. De la connaissance précédente des caractéristiques du mécanisme de substitution, nous savons que l'équipe
[me@linuxbox ~]$ echo $foo
est exposé au mécanisme de substitution de paramètres, à la suite de quoi il prend la forme
[me@linuxbox ~]$ echo yes
D'un autre côté, l'équipe
[me@linuxbox ~]$ echo $fool
se transforme en
[me@linuxbox ~]$ echo
Rien ne remplace une variable vide! Cela peut provoquer des erreurs dans les commandes qui nécessitent des arguments. Par exemple:
[me@linuxbox ~]$ foo=foo.txt [me@linuxbox ~]$ foo1=foo1.txt [me@linuxbox ~]$ cp $foo $fool cp: 'foo.txt' , "cp --help" .
Nous avons attribué des valeurs à deux variables, foo et foo1. Et puis ils ont essayé d'exécuter la commande cp, mais ils ont fait une faute de frappe au nom du deuxième argument. Après traitement par le moteur de recherche, la commande cp n'a reçu qu'un seul argument, bien qu'il en nécessite deux.
Voici quelques règles pour nommer les variables:
- Les noms de variable peuvent être constitués de caractères alphanumériques (lettres et chiffres) et de soulignements.
- Le premier caractère d'un nom de variable ne peut être qu'une lettre ou un trait de soulignement.
- La présence d'espaces et de signes de ponctuation dans les noms de variables n'est pas autorisée.
La
variable nom signifie une valeur qui peut changer, et dans de nombreuses applications, les variables sont utilisées de cette façon. Cependant, la variable de titre dans notre application est utilisée comme
constante . Une constante, comme une variable, a un nom et contient une valeur. La seule différence est que la valeur de la constante ne change pas. Dans une application qui effectue des calculs géométriques, vous pouvez définir une constante PI avec une valeur de 3,1415, au lieu d'utiliser ce nombre tout au long du programme. Le shell ne fait pas de distinction entre les constantes et les variables; Ces termes sont utilisés principalement pour la commodité du programmeur. Une convention typique consiste à utiliser des lettres majuscules pour indiquer des constantes et des lettres minuscules pour les vraies variables. Modifions le scénario pour le mettre en conformité avec cette convention:
#!/bin/bash # TITLE="System Information Report For $HOSTNAME" echo "<html> <head> <title>$TITLE</title> </head> <body> <h1>$TITLE</h1> </body> </html>"
En cours de route, nous avons complété le nom en ajoutant à la fin la valeur de la variable shell HOSTNAME. Il s'agit du nom de réseau de la machine.
REMARQUE
En fait, le shell a un mécanisme pour garantir l'immuabilité des constantes, sous la forme d'une commande de déclaration intégrée avec le paramètre -r (lecture seule - lecture seule). Si vous affectez une valeur à la variable TITLE comme indiqué ci-dessous:
declare -r TITLE="Page Title"
le shell ne permettra pas de réaffecter la valeur à la variable TITLE. Ce mécanisme est rarement utilisé dans la pratique, mais il est disponible et peut être utilisé dans des scénarios particulièrement rigoureux.
Affectation de valeurs aux variables et constantes
Nous sommes arrivés au moment où notre connaissance des caractéristiques du fonctionnement du mécanisme de substitution commence à porter ses fruits. Comme nous l'avons vu, l'attribution de valeurs aux variables se fait comme suit:
=
où la
variable est le nom de la variable et la
valeur est la chaîne. Contrairement à certains autres langages de programmation, le shell ne se soucie pas des types de valeurs attribuées aux variables; elle interprète toutes les valeurs comme des chaînes. Il est possible de forcer le shell à limiter la plage de valeurs affectées aux entiers en utilisant la commande declare avec l'option -i, mais comme pour déclarer des variables en lecture seule, cette fonctionnalité est rarement utilisée dans la pratique.
Notez qu'il n'y a aucun espace dans l'opérateur d'affectation entre le nom de variable, le signe égal et la valeur. Et en quoi peut consister le sens? De tout, vous pouvez développer une chaîne.
a=z # a "z". b="a string" # . c="a string and $b" # , # , . d=$(ls -l foo.txt) # . e=$((5 * 7)) # . f="\t\ta string\n" # , # .
Sur une même ligne, vous pouvez affecter plusieurs variables à la fois:
a=5 b="a string"
Lors de l'utilisation de la substitution, les noms de variables peuvent être placés entre accolades facultatives {}. Ceci est utile lorsque le nom de variable devient ambigu dans le contexte environnant. L'exemple suivant tente de renommer
mon fichier en
mon fichier1 à l'aide d'une variable:
[me@linuxbox ~]$ filename="myfile" [me@linuxbox ~]$ touch $filename [me@linuxbox ~]$ mv $filename $filename1 mv: 'myfile' , "mv --help" .
Cette tentative a échoué car le shell a interprété le deuxième argument de la commande mv comme le nom d'une nouvelle variable (et vide). Ce qui suit montre comment résoudre ce problème:
[me@linuxbox ~]$ mv $filename ${filename}1
En ajoutant des accolades, nous nous sommes assurés que le shell n'interpréterait pas le dernier caractère 1 comme faisant partie du nom de la variable.
Remarque
Lors de la substitution, il est recommandé de placer les noms de variable et les commandes entre guillemets doubles pour empêcher le shell de couper les lignes en mots. Il est particulièrement important d'utiliser des guillemets lorsqu'une variable peut contenir un nom de fichier.
Nous utiliserons cette opportunité pour ajouter des données supplémentaires au rapport, à savoir la date et l'heure du rapport, ainsi que le nom de l'utilisateur qui a créé le rapport:
#!/bin/bash # TITLE="System Information Report For $HOSTNAME" CURRENT_TIME=$(date +"%x %r %Z") TIME_STAMP="Generated $CURRENT_TIME, by $USER" echo "<html> <head> <title>$TITLE</title> </head> <body> <h1>$TITLE</h1> <p>$TIME_STAMP</p> </body> </html>"
Documents intégrés
Nous avons examiné deux méthodes de sortie de texte différentes, et les deux utilisent la commande echo. Cependant, il existe une troisième méthode, appelée
document en ligne (ici document), ou
script en ligne (ici script). Un document incorporé est une forme supplémentaire de redirection d'E / S qui transmet le texte incorporé dans un script à l'entrée de commande standard. Cette redirection fonctionne comme ceci:
<<
où la
commande est le nom de la commande qui reçoit le texte spécifié via une entrée standard, et l'
indicateur est la ligne marquant la fin du texte incorporé. Nous allons modifier le scénario en utilisant le document incorporé qu'il contient:
#!/bin/bash # TITLE="System Information Report For $HOSTNAME" CURRENT_TIME=$(date +"%x %r %Z") TIME_STAMP="Generated $CURRENT_TIME, by $USER" cat << _EOF_ <html> <head> <title>$TITLE</title> </head> <body> <h1>$TITLE</h1> <p>$TIME_STAMP</p> </body> </html> _EOF_
Au lieu de la commande echo, le script utilise désormais la commande cat et le document incorporé. La ligne _EOF_ a été choisie pour le rôle d'indicateur (signifie
fin de fichier -
fin de fichier , accord commun) et marque la fin du texte incorporé. Veuillez noter que la ligne d'indicateur doit être dans une ligne distincte, une et aucun espace ne doit la suivre.
Mais quels sont les avantages de l'utilisation du document intégré ici? Pratiquement aucune, sauf que les guillemets à l'intérieur des documents intégrés perdent leur signification particulière pour le shell. Voici un exemple d'utilisation d'un document incorporé sur la ligne de commande:
[me@linuxbox ~]$ foo="some text" [me@linuxbox ~]$ cat << _EOF_ > $foo > "$foo" > '$foo' > \$foo > _EOF_ some text "some text" 'some text' $foo
Comme vous pouvez le voir, le shell de commande ne fait pas attention aux guillemets. Elle les interprète comme des personnages ordinaires. Grâce à cela, nous insérons librement des guillemets dans les documents intégrés. Cette circonstance peut être utilisée lors de l'élaboration de programmes de déclaration.
Les documents intégrés peuvent être utilisés avec toutes les commandes qui acceptent les données d'une entrée standard. L'exemple suivant utilise un document intégré pour envoyer une séquence de commandes au programme ftp pour télécharger un fichier à partir d'un serveur FTP distant:
#!/bin/bash # FTP FTP_SERVER=ftp.nl.debian.org FTP_PATH=/debian/dists/stretch/main/installer-amd64/current/images/cdrom REMOTE_FILE=debian-cd_info.tar.gz ftp -n << _EOF_ open $FTP_SERVER user anonymous me@linuxbox cd $FTP_PATH hash get $REMOTE_FILE bye _EOF_ ls -l $REMOTE_FILE
Si vous remplacez l'opérateur de redirection << par << -, le shell de commande ignorera les caractères de tabulation initiaux dans le document incorporé. Grâce à cela, des retraits peuvent être ajoutés au document intégré pour une meilleure lisibilité:
#!/bin/bash # FTP FTP_SERVER=ftp.nl.debian.org FTP_PATH=/debian/dists/stretch/main/installer-amd64/current/images/cdrom REMOTE_FILE=debian-cd_info.tar.gz ftp -n <<- _EOF_ open $FTP_SERVER user anonymous me@linuxbox cd $FTP_PATH hash get $REMOTE_FILE bye _EOF_ ls -l $REMOTE_FILE
Cependant, l'utilisation de cette fonctionnalité n'est pas toujours pratique, car pour l'indentation, de nombreux éditeurs de texte (et les programmeurs eux-mêmes) préfèrent utiliser des caractères d'espace au lieu d'onglets.
Conclusion
Dans ce chapitre, nous avons commencé à développer un projet avec lequel nous passerons par toutes les étapes de la création d'un script. Nous nous sommes familiarisés avec les variables et les constantes et les caractéristiques de leur utilisation. Ils sont plus souvent utilisés que les autres composants logiciels pour la substitution. Nous avons également vu comment organiser la sortie d'informations dans un script et nous sommes familiarisés avec différentes méthodes d'intégration de blocs de texte.
À propos de l'auteur
William Shotts est un développeur de logiciels professionnel avec plus de 30 ans d'expérience qui utilise activement le système d'exploitation Linux depuis plus de 20 ans. Il possède une vaste expérience dans le développement de logiciels, le support technique, le contrôle qualité et la rédaction de documentation. Il est également le créateur de LinuxCommand.org, un site d'éducation et de sensibilisation Linux qui publie des nouvelles, des critiques et est pris en charge par la ligne de commande Linux.
À propos de Science Editor
Jordi Gutiérrez Hermoso est programmeur informatique, mathématicien et hacker éthique. Depuis 2002, il utilise exclusivement Debian GNU / Linux, non seulement à la maison, mais aussi au travail. Jordi est impliqué dans le développement de GNU Octave, un environnement informatique libre largement compatible avec Matlab, ainsi que Mercurial, un système de contrôle de version distribué. Il aime les mathématiques pures et appliquées, le patin à glace, la natation et le tricot. Récemment, il réfléchit beaucoup aux problèmes des émissions de gaz à effet de serre et participe à des actions pour sauver les rhinocéros.
»Plus d'informations sur le livre sont disponibles sur
le site Web de l'éditeur»
Contenu»
Extrait25% de réduction sur les colporteurs -
LinuxLors du paiement de la version papier du livre, un livre électronique est envoyé par e-mail.