LA CLOCHE

Il y a ceux qui ont lu cette nouvelle avant vous.
Abonnez-vous pour recevoir les derniers articles.
Email
Nom
Nom de famille
Comment voulez-vous lire The Bell
Pas de spam

Qu'est-ce qu'une coque et pourquoi est-elle nécessaire

Le shell de commande de tous les systèmes de type Unix, auquel appartient GNU / Linux, est un programme régulier qui s'exécute à la fois dans une console texte (qui est de moins en moins utilisée) et dans un environnement graphique - dans une fenêtre d'émulateur de terminal disponible sur n'importe quel système Linux. ...

Sa tâche est simple et évidente: accepter une ou plusieurs lignes d'entrée, les analyser, et en fonction des résultats de cette analyse, réagir en conséquence - exécuter une commande, exécuter un programme, afficher un message de diagnostic, etc.

Dans presque tous distributions Linux bash est le shell par défaut pour les utilisateurs (Bourne Again SHell est un autre shell Bourne; Steve Bourne est l'auteur du premier shell Unix, sh). En fait, il est devenu une norme non officielle, et son amélioration fonctionnalité continue sans interruption. Il existe d'autres shells de commandes - tcsh (version C-shell), ksh (Korn Shell), zsh, etc. - chacun a ses propres avantages et inconvénients, ainsi que ses propres groupes de fans. Néanmoins, bash est plus familier aux larges masses d'utilisateurs avec différents niveaux de compétences, c'est pourquoi j'ai opté pour cela. Il est également intéressant de noter que quelles que soient les capacités des différents obus, ils sont tous compatibles avec leur ancêtre idéologique - Bourn Shell (sh). En d'autres termes, un script écrit pour sh fonctionnera correctement dans n'importe quel shell moderne (à l'inverse, en général, ce n'est pas vrai).

Avantages de la ligne de commande

La question peut se poser: pourquoi s'embêter avec la ligne de commande, s'il existe des interfaces graphiques pratiques et belles? Il y a plusieurs raisons à cela. Premièrement, toutes les opérations ne sont pas plus pratiques et plus rapides à effectuer à l'aide d'une interface graphique. Deuxièmement, chaque programme suit le principe fondamental des systèmes Unix: faire un travail bien défini et bien le faire. En d'autres termes, vous comprenez toujours ce qui se passe lorsque vous exécutez tel ou tel utilitaire (si quelque chose n'est pas entièrement clair, alors vous devriez consulter le manuel). Troisièmement, maîtrisant les commandes, essayant leurs combinaisons et combinaisons de leurs paramètres, l'utilisateur étudie le système et acquiert une expérience pratique précieuse. Vous avez accès à des outils puissants tels que des pipelines pour enchaîner des commandes pour traiter des données, une redirection d'E / S et vous pouvez programmer directement à partir du shell. Peut-être vaut-il la peine de s'attarder sur la programmation plus en détail, d'autant plus que de nombreux scripts système sous Linux (par exemple, des scripts pour démarrer les services système) sont écrits pour le shell.

Le shell de commande comme langage de programmation

Ainsi, le shell de commande peut être considéré à la fois comme un langage de programmation et comme un environnement d'exécution de logiciel. Bien sûr, ce langage n'est pas compilé, mais interprété. Il permet l'utilisation de variables: système ou propre. La séquence d'exécution des commandes du programme est modifiée à l'aide de constructions permettant de vérifier la condition et de choisir l'option appropriée: if-then-else et case. Les boucles While, Until et for vous permettent d'automatiser les actions répétitives. Il est possible de combiner des groupes de commandes en blocs logiques. Vous pouvez même écrire des fonctions réelles en passant des paramètres. Ainsi, il y a tous les signes et caractéristiques d'un langage de programmation à part entière. Essayons d'en tirer un double avantage - en plus d'apprendre les bases de la programmation, nous automatiserons notre travail quotidien.

Bonjour le monde! Système de sauvegarde simple

Le besoin de copie de réserve Tout le monde connaît les données, mais les utilisateurs n'ont jamais assez de temps pour cette opération ennuyeuse. La solution est simple: organiser création automatique sauvegardes. Ce sera notre première mission de programmation shell.

#! / bin / bash # # Sauvegarde des répertoires et des fichiers de votre répertoire personnel # Ce script de commande peut être exécuté automatiquement avec cron # cd $ HOME si [! -d archives] puis archives mkdir fi cur_date \u003d `date +% Y% m% d% H% M` if [$ # -eq 0]; then tar czf archive $ (cur_date) .tar.gz projets bin else tar czf archive $ (cur_date) .tar.gz $ * fi if [$? \u003d 0]; then mv archive $ (cur_date) .tar.gz $ HOME / archives echo "$ cur_date - Sauvegarde terminée avec succès." else echo "ERREUR $ cur_date pendant la sauvegarde." Fi

Tout script de commande (script - un script, les soi-disant programmes shell) commence par une ligne d'identifiant, qui spécifie explicitement l'interpréteur de commandes avec le chemin complet vers lui. Le chemin complet est une liste séquentielle de tous les répertoires, à partir de la racine, qui doit être entré pour accéder au fichier cible, et, bien sûr, le nom de ce fichier. L'enregistrement du chemin complet est extrêmement important pour identifier de manière unique chaque fichier dans la hiérarchie du système de fichiers.

Quatre lignes de commentaires suivent. Dès que le shell rencontre un caractère "#", il considère tous les caractères suivants comme des commentaires et les ignore complètement jusqu'à la fin de la ligne courante. Par conséquent, un commentaire peut être lancé non pas depuis le tout début d'une ligne, mais accompagné d'une commande.

Les commentaires sont suivis d'une ligne vide. Cela ne signifie rien pour le shell et aucune action n'est entreprise. Dans les scripts, des lignes vides sont généralement insérées pour rendre le code plus facile à lire.

Finalement, nous sommes arrivés à la première "vraie" équipe. Il vous permet de changer le répertoire (Change Directory), c'est-à-dire passer du répertoire courant à un autre passé à la commande en argument. Dans la plupart des cas, le répertoire cible est spécifié explicitement, par exemple, les projets cd / tmp ou cd, mais dans notre cas, la variable système prédéfinie HOME est utilisée - elle contient le chemin complet du répertoire personnel utilisateur actuel, au nom duquel le script de commande est exécuté. Ainsi, nous nous débarrassons de la nécessité d'apporter des modifications au code à chaque fois que nous changeons d'utilisateur, car la commande renvoie n'importe qui dans son répertoire personnel. Le signe dollar "$" devant un nom de variable signifie que vous devez extraire la valeur contenue dans cette variable et la remplacer dans la ligne de commande au lieu de son nom. Il convient de noter en particulier que dans un langage de commande shell, les lettres majuscules sont importantes; HOME, Home et Home sont trois variables différentes. Par convention, les lettres majuscules désignent les noms des variables système: HOME, PATH, EDITOR, etc. Cette convention n'interdit pas aux utilisateurs de créer leurs propres variables avec des noms en majuscules, mais pourquoi se compliquer la tâche en violant les règles et réglementations généralement acceptées? Il est également déconseillé de modifier les valeurs des variables système à moins que cela ne soit absolument nécessaire. En général, nous observons une règle simple: nous n'utilisons des variables système que pour la lecture, et si nous avions besoin des nôtres, nous écrivons son nom en minuscules.

Notre première commande pourrait être écrite plus succinctement:

cd ~

Ici, le symbole "~" désigne également le répertoire personnel de l'utilisateur actuel. Les vétérans de la ligne de commande sont encore plus laconiques:

CD

Le fait est que lorsqu'aucun argument n'est donné à la commande cd, elle passe au répertoire personnel.

L'étape suivante est la construction logicielle classique consistant à vérifier une condition et à prendre une décision appropriée. Le schéma général est le suivant:

si<условие> puis<одна или несколько команд> Fi

Le dernier mot de la construction (s'il est dans l'ordre inverse) agit comme une parenthèse fermante, c'est-à-dire les limites de la liste des commandes exécutées si la condition est vraie. La présence de fi est requise même s'il n'y a qu'une seule commande dans la liste.

Pour tester une condition, en règle générale, la commande de test ou sa forme alternative entre crochets est utilisée. En d'autres termes, les enregistrements

si [! -d archives] si test! -d archives

sont absolument équivalents. je préfère crochets, car ils définissent plus clairement les limites de la condition vérifiée. Les parenthèses droite et gauche doivent être séparées de la condition par des espaces.

Les critères de vérification de la condition sont définis par différents indicateurs. La commande de test en reconnaît une très grande liste. Dans notre exemple, l'indicateur -d est utilisé pour vérifier si le nom spécifié après l'indicateur correspond à un vrai répertoire (répertoire). Les indicateurs les plus couramment utilisés lors de l'utilisation de fichiers sont:

F - existe-t-il un fichier régulier avec le nom donné;

R - est le droit d'en lire pour le fichier spécifié;

W - si le fichier spécifié a le droit d'y écrire;

X - si le droit de l'exécuter est défini pour le fichier spécifié;

S - si le fichier spécifié a une taille non nulle.

Dans notre cas, la condition est précédée d'un point d'exclamation, indiquant l'opération de négation logique, de sorte que la signification de la condition vérifiée devient absolument opposée. Essayons d'écrire la signification de ces commandes en russe clair:

si [! -d archives] Si le répertoire des archives n'existe pas (dans le répertoire courant) alors lancez l'exécution du bloc de commande: mkdir archives crée le répertoire des archives (dans le répertoire courant) fi termine le bloc de commande.

Comme vous pouvez le voir, tout s'est avéré pas si compliqué. Avec un peu de pratique, vous pouvez facilement lire et créer vous-même de tels designs. La commande pour créer le catalogue est tellement explicite qu'aucune autre explication n'est requise.

Sur la ligne suivante, nous créons notre propre variable locale cur_date. Dans la grande majorité des cas, les variables sont créées en attribuant simplement une valeur spécifique, par exemple:

ten \u003d 10 string \u003d "Ceci est une chaîne de texte"

Mais dans notre exemple, une petite astuce est appliquée. Veuillez noter qu'après le signe égal - le caractère d'affectation - la commande est écrite entre guillemets. Cette forme de notation permet d'affecter à une variable non pas la chaîne elle-même, mais le résultat de son exécution. Voici la sortie de la commande date qui renvoie date actuelle et l'heure au format spécifié par la liste de paramètres:

% Y - année en cours en forme complète, c'est à dire. quatre chiffres (par exemple, 2009);

% m - le numéro du mois en cours (par exemple, 09 - pour septembre);

% d - numéro du jour en cours;

% H - heure actuelle au format 24 heures;

% M est la minute actuelle.

Ainsi, si vous exécutez la commande

cur_date \u003d `date +% Y% m% d% H% M`

le 10 septembre 2009 à 22h45, la valeur de chaîne "200909102245" sera affectée à cur_date. Le but de cette astuce est de générer un nom de fichier d'archive unique et non dupliqué. Si vous avez l'intention d'exécuter plusieurs instances du programme en une minute, vous pouvez améliorer l'unicité des noms en ajoutant également les secondes actuelles. Comment? Consultez le manuel de l'utilitaire de date (man date) - il n'y a rien de difficile à ce sujet.

Avant de procéder à la création du fichier archive, il est nécessaire de déterminer les répertoires que nous y enregistrerons. Pour plus de flexibilité, vous pouvez spécifier un ensemble de répertoires à archiver par défaut, mais envisagez de remplacer cet ensemble par une liste de répertoires passée en argument à notre script de commande. Pour cela, des variables shell spéciales sont utilisées: $ # - le nombre de paramètres passés au script et $ * - tous les paramètres passés au format d'une ligne.

si [$ # -eq 0]; puis

Vérifier la condition "si le nombre de paramètres passés est nul", puis exécuter la commande suivante. Notez que le mot-clé then peut être écrit dans la chaîne de conditions en le séparant de l'expression conditionnelle par un point-virgule.

archive tar czf $ (cur_date) .tar.gz projets bin

Commande pour créer un fichier d'archive et compresser ce fichier. L'utilitaire tar lui-même n'effectue aucune compression, il ne compile que tous les fichiers et répertoires spécifiés dans un seul fichier tar. Le premier drapeau est destiné à cela - c (créer - créer). La compression est effectuée par un programme externe - ici il s'agit de gzip, invoqué par le deuxième drapeau - z. Si le programme de compression bzip2 le plus efficace est installé sur votre système, vous pouvez l'utiliser en modifiant la commande comme suit:

archive tar cjf $ (cur_date) .tar.bz2 projets bin

Le troisième drapeau, f, indique que le nom du fichier d'archive suit, donc c'est toujours le dernier dans la liste des indicateurs. Notez que le nom de la variable est entouré d'accolades lors de la substitution. Ceci est fait pour mettre en évidence explicitement la variable dans la chaîne environnante, éliminant ainsi de nombreux problèmes potentiels. Les extensions du fichier archive ne sont pas attribuées automatiquement, vous ajoutez vous-même tout ce dont vous avez besoin. J'ai répertorié les projets et bin comme répertoires archivés par défaut, mais vous pouvez noter ici les noms de vos répertoires les plus précieux.

Le mot-clé else ouvre une autre branche d'exécution. Les commandes de ce bloc commencent à fonctionner si le contrôle de condition donne le résultat "faux" (dans notre exemple: "le nombre de paramètres passés est différent de zéro", c'est-à-dire que l'utilisateur a spécifié les noms des répertoires). Dans ce cas, la commande ressemblera à ceci:

archive tar czf $ (date_cur) .tar.gz $ *

Ici, les répertoires par défaut sont remplacés par une chaîne de nom de répertoire acceptée de l'extérieur. Il est possible d'accepter et de traiter chaque paramètre externe séparément, mais il est plus pratique pour nous de passer la chaîne entière.

A la fin du programme, un autre contrôle est effectué. Dans les environnements Unix, toutes les commandes renvoient un code d'état d'arrêt. Si la commande réussit, elle renvoie le code 0, sinon le code de sortie sera différent de zéro. Pour vérifier le succès de la commande d'archive précédente, utilisons une autre variable spéciale $?, Qui contient toujours la valeur du code de sortie de la commande la plus récente. Si la variable $? contient 0, c'est-à-dire le fichier de sauvegarde a été créé avec succès, puis nous le déplaçons dans le répertoire d'archive:

archive mv $ (date_cur) .tar.gz $ HOME / archives

et émettez le message approprié:

echo "$ cur_date - Sauvegarde terminée avec succès."

Si le contrôle a montré que le code de fin de l'opération d'archivage est différent de zéro, un message d'erreur s'affiche:

echo "$ cur_date - ERREUR pendant la sauvegarde."

Ceci termine le travail de notre script de commande.

Pour tester le fonctionnement de notre programme, vous devez enregistrer ce qui précède la source dans un fichier, par exemple, nommé bckp, puis rendez-le exécutable pour plus de commodité:

chmod 750 bckp

et courir:

./bckp

pour sauvegarder les répertoires par défaut et

./bckp docs progs fonctionne

pour créer une copie de sauvegarde des répertoires répertoriés (incluez les noms des répertoires qui existent réellement sur votre système, sinon vous recevrez une erreur)

Vous pouvez placer le fichier bckp dans l'un des répertoires spécifiés dans la variable système PATH. Les emplacements les plus préférés sont / usr / local / bin ou $ HOME / bin si vous en avez un. Après cela, vous pouvez exécuter bckp en tant que commande système.

Comment automatiser les sauvegardes planifiées

Quelques mots sur la sauvegarde automatisée. À cette fin, le programmateur cron système est utilisé, qui lit les instructions de travail à partir d'un fichier crontab spécial. Pour définir de telles instructions, vous devez créer et modifier votre fichier crontab à l'aide de la commande:

crontab -e

Les instructions sont écrites dans un format strictement défini (les champs sont séparés par des espaces):

minutes heures jour_ du mois mois jour_ de la semaine commande

L'une des options de planification des sauvegardes peut ressembler à ceci:

30 23 10,20,30 * * / usr / local / bin / bckp

Cela signifie que le script de sauvegarde (vous devez spécifier le chemin complet de ce fichier) s'exécutera à 23h30 les 10, 20 et 30 de chaque mois, quel que soit le jour de la semaine. (Les astérisques représentent toute la plage de valeurs valide, dans ce cas: tous les mois - dans le 4e champ, n'importe quel jour de la semaine - dans le 5e champ)

Si vous préférez résumer par semaine et que votre système fonctionne 24 heures sur 24, il est judicieux de planifier des sauvegardes pendant les heures de service léger:

0 5 * * 3.5 / usr / local / bin / bckp

Ici sauvegardes sera généré à 5h00 les mercredis et vendredis de chaque mois (un astérisque dans le 4e champ), quel que soit le numéro (un astérisque dans le 3e champ).

Vous pouvez découvrir toutes les subtilités de la planification dans man 5 crontab.

Résultats et conclusions

Le scénario de sauvegarde décrit dans cet article a des fonctionnalités modestes. Mais ce n'était pas sa tâche principale, mais que le lecteur comprenait ce qui peut être fait en ligne de commande, et non seulement copié et suivi les suggestions fichier batch, mais s'est intéressé à étendre ses fonctions, a commencé à rechercher les immenses possibilités offertes par les obus de commande. Et si quelqu'un, après avoir lu cet article, essaie d'améliorer le code donné ici, ou écrit sa propre version, ou implémente sa propre idée indépendante, alors je considérerai que l'objectif principal a été atteint.

Télécharger les ressources

static.content.url \u003d http: //www.site/developerworks/js/artrating/

ArticleID \u003d 458335

ArticleTitle \u003d Principes de base de la programmation shell

  • Didacticiel

Bases de BASH. Partie 2.
Je m'excuse pour un si long délai entre les articles, mais la session se fait sentir au moment le plus inopportun :)
Merci à tous pour les commentaires, critiques et ajouts qui ont été exprimés dans les commentaires du dernier article.
Cette partie, comme promis, sera consacrée aux boucles, aux opérations mathématiques et à l'utilisation de commandes externes.
Commençons.

Cycles. Boucle For-in.

L'opérateur for-in est destiné à un accès alterné aux valeurs répertoriées dans la liste. Chaque valeur de la liste est affectée à une variable à son tour.
La syntaxe est la suivante:
pour variable dans list_values
faire
commandes
terminé

Regardons un petit exemple:

#! / bin / bash
pour i en 0 1 2 3 4 # variable $ i nous attribuerons des valeurs de 0 à 4 inclusivement
faire
echo "Le numéro de console est $ i" \u003e\u003e / dev / pts / $ i # Écrivez la chaîne "Le numéro de console est $ i" dans / dev / pts / $ i (fichier de terminal virtuel)
done # boucle est terminée
sortie 0

Après avoir exécuté l'exemple, une ligne avec son numéro apparaîtra dans les 5 premières consoles virtuelles (terminaux). Les valeurs de la liste sont remplacées dans la variable $ i une par une et la boucle travaille avec la valeur de cette variable

Cycles. Alors que la boucle.

La boucle while est plus complexe que la boucle for-in et est utilisée pour répéter des commandes tant qu'une expression est vraie (code retour \u003d 0).
La syntaxe de l'opérateur est la suivante:
while expression ou commande renvoyant le code de retour
faire
commandes
terminé

Prenons un exemple de cycle en utilisant l'exemple suivant:

#! / bin / bash
again \u003d yes # attribuer à nouveau "yes" à la variable
while ["$ again" \u003d "yes"] # Bouclons jusqu'à ce que $ soit à nouveau égal à "yes"
faire
echo "Veuillez saisir un nom:"
lire le nom
echo "Le nom que vous avez entré est $ name"

Echo "Voulez-vous continuer?"
lire à nouveau
terminé
echo "Bye-Bye"


Et maintenant le résultat du script:
[email protected]: ~ $ ./bash2_primer1.sh
Veuillez saisir un nom:
ite
Le nom que vous avez entré est ite
Souhaitez-vous continuer?
Oui
Veuillez saisir un nom:
Mihail
Le nom que vous avez entré est mihail
Souhaitez-vous continuer?
non
Bye Bye

Comme vous pouvez le voir, le cycle est exécuté jusqu'à ce que nous entrions autre chose que "oui". Entre faire et terminé, vous pouvez décrire toutes les structures, instructions, etc., toutes seront exécutées dans une boucle. Mais vous devez être prudent avec cette boucle, si vous exécutez une commande sans changer la variable d'expression, vous pouvez entrez dans une boucle sans fin.
Maintenant sur la condition de vérité. Après un certain temps, comme dans l'instruction conditionnelle if-then-else, vous pouvez insérer n'importe quelle expression ou commande qui renvoie un code de retour, et la boucle sera exécutée tant que le code de retour \u003d 0! L'opérateur "[" est analogue à la commande de test, qui vérifie la véracité de la condition qui lui a été transmise.

Regardons un autre exemple, je l'ai pris dans le livre Advanced Bash Scripting. J'ai beaucoup aimé :), mais je l'ai un peu simplifié. Dans cet exemple, nous allons nous familiariser avec un autre type de boucles UNTIL-DO.... C'est presque un analogue complet de la boucle WHILE-DO, seulement il est exécuté alors qu'une expression est fausse.
Voici un exemple:

#! / bin / bash
echo "Entrez le numérateur:"
lire le dividende
echo "Entrez le dénominateur:"
lire le diviseur

Dnd \u003d $ dividende # nous allons changer les variables de dividende et de diviseur,
# sauvegarder leurs connaissances dans d'autres variables, car ils nous
# aura besoin
dvs \u003d $ diviseur
reste \u003d 1

Jusqu'à ["$ reste" -eq 0]
faire
soit "reste \u003d dividende% diviseur"
dividende \u003d $ diviseur
diviseur \u003d $ reste
terminé

Écho "GCD de $ dnd et $ dvs \u003d $ dividende"


Le résultat de l'exécution du script:
[email protected]: ~ $ ./bash2_primer3.sh
Entrez le numérateur:
100
Entrez le dénominateur:
90
GCD des nombres 100 et 90 \u003d 10

Opérations mathématiques

Laissez la commande.
La commande Let effectue des opérations arithmétiques sur les nombres et les variables.
Regardons un petit exemple dans lequel nous effectuons quelques calculs sur les nombres saisis:
#! / bin / bash
echo "Entrez un:"
lire un
echo "Entrez b:"
lire b

Soit "c \u003d a + b" # addition
echo "a + b \u003d $ c"
soit "c \u003d a / b" # division
echo "a / b \u003d $ c"
laissez "c<<= 2" #сдвигает c на 2 разряда влево
echo "c après décalage de 2 chiffres: $ c"
soit "c \u003d a% b" # trouver le reste de a divisé par b
echo "$ a / $ b. reste: $ c"


Résultat de l'exécution:
[email protected]: ~ $ ./bash2_primer2.sh
Entrez un:
123
Entrez b:
12
a + b \u003d 135
a / b \u003d 10
c après un décalage de 2 bits: 40
123/12. Solde: 3

Bon, comme vous pouvez le voir, rien de compliqué, la liste des opérations mathématiques est standard:
+ - ajout
- - soustraction
* - multiplication
/ - division
** - exponentiation
% - module (division modulo), reste de la division
let vous permet d'utiliser des commandes arithmétiques abrégées, réduisant ainsi le nombre de variables utilisées. Par exemple: a \u003d a + b équivaut à a + \u003d b, etc.

Travailler avec des programmes externes lors de l'écriture de scripts shell

Tout d'abord, une petite théorie utile.
Redirection de flux.
Bash (comme beaucoup d'autres shells) a des descripteurs de fichier intégrés: 0 (stdin), 1 (stdout), 2 (stderr).
stdout - Sortie standard. Tout ce qui programme la sortie va ici
stdin - Entrée standard. C'est tout ce que l'utilisateur tape dans la console
stderr - Sortie d'erreur standard.
Pour les opérations avec ces descripteurs, il existe des caractères spéciaux:\u003e (redirection de sortie),< (перенаправление ввода). Оперировать ими не сложно. Например:
rediriger la sortie de cat / dev / random vers / dev / null (opération absolument inutile :))) ou
écrire le contenu du répertoire courant dans le fichier de liste (déjà plus utile)
S'il est nécessaire d'ajouter au fichier (lorsque vous utilisez "\u003e", il sera remplacé), au lieu de "\u003e", utilisez "\u003e\u003e"
après avoir demandé un mot de passe à sudo, il sera extrait du fichier my_password comme si vous l'aviez saisi à partir du clavier.
Si vous avez besoin d'écrire dans le fichier uniquement des erreurs qui pourraient survenir pendant le fonctionnement du programme, vous pouvez utiliser:
./program_with_error 2\u003e fichier_erreur
le chiffre 2 avant "\u003e" signifie que vous devez rediriger tout ce qui entre dans le descripteur 2 (stderr).
Si vous devez forcer stderr à écrire sur stdout, vous pouvez suivre. façon:
le caractère "&" signifie le pointeur vers le descripteur 1 (stdout)
(Par défaut, stderr écrit sur la console où l'utilisateur travaille (entre-temps, écrit sur l'écran)).
2. convoyeurs.
Le pipeline est un outil très puissant pour travailler avec la console Bash. La syntaxe est simple:
team1 | commande 2 - signifie que la sortie de la commande 1 sera transmise à l'entrée de la commande 2
Les pipelines peuvent être regroupés en chaînes et en sortie à l'aide de la redirection de fichiers, par exemple:
ls -la | grep "hash" | sort\u003e sortilg_list
la sortie de la commande ls -la est redirigée vers grep, qui sélectionne toutes les lignes contenant le mot hachage, et redirigée vers la commande sort, qui écrit le résultat dans le fichier sorting_list. Tout est assez clair et simple.

Le plus souvent, les scripts Bash sont utilisés pour automatiser certaines opérations de routine dans la console, il devient donc parfois nécessaire de traiter le stdout d'une commande et de le transférer vers stdin vers une autre commande, tandis que le résultat de l'exécution d'une commande doit être traité d'une manière ou d'une autre. Dans cette section, j'essaierai d'expliquer les principes de base du travail avec des commandes externes dans un script. Je pense que j'ai donné suffisamment d'exemples et maintenant vous ne pouvez écrire que les points principaux.

1. Passer la sortie à une variable.
Pour écrire la sortie d'une commande dans une variable, il suffit de mettre la commande entre guillemets, par exemple
a \u003d `echo" qwerty "`
echo $ a

Résultat du travail: qwerty


Cependant, si vous souhaitez écrire une liste de répertoires dans une variable, vous devez traiter correctement le résultat pour placer les données dans la variable. Prenons un petit exemple:
LISTE \u003d `find / svn / -type d 2\u003e / dev / null | awk "(FS \u003d" / ") (imprimer $ 4)" | trier | uniq | tr "\\ n" "" `
pour ONE_OF_LIST dans $ LIST
faire
svnadmin hotcopy / svn / $ ONE_OF_LIST / svn / temp4backup / $ ONE_OF_LIST
terminé

Ici, nous utilisons une boucle for-do-done pour archiver tous les répertoires du dossier / svn / avec la commande svnadmin hotcopy (ce qui dans notre cas n'a pas d'importance, juste à titre d'exemple). La ligne LIST \u003d `find / svn / -type d 2\u003e / dev / null | awk "(FS \u003d" / ") (imprimer $ 4)" | trier | uniq | tr "\\ n" "" `Dans celui-ci, la variable LIST est affectée à l'exécution de la commande find traitée par les commandes awk, sort, uniq, tr (nous ne considérerons pas toutes ces commandes, car il s'agit d'un article séparé). La variable LIST contiendra les noms de tous les répertoires du dossier / svn / placés sur une seule ligne (afin de le purger dans la boucle.

Comme vous pouvez le voir, tout n'est pas difficile, il suffit de comprendre le principe et d'écrire quelques-uns de vos scripts. À la fin de l'article, je voudrais vous souhaiter le meilleur dans l'apprentissage de BASH et de Linux en général. La critique, comme d'habitude, est la bienvenue. Le prochain article sera probablement consacré à l'utilisation de programmes tels que sed, awk.

Degtyarev E.K. Shell est un interpréteur pour les commandes issues du terminal ou d'un fichier batch. il programme régulier (c'est-à-dire non inclus dans le noyau système opérateur UNIX). Vous pouvez le remplacer par un autre ou en avoir plusieurs. Les deux versions les plus connues: - Shell (version 7 UNIX) ou Bourne Shell (du nom de l'auteur S.R.Bourne de Bell Labs); - C-Shell (versions Berkley UNIX). Ils sont similaires, mais il y a quelques différences: C-Shell est plus puissant en mode dialogue, tandis que Shell standard a des structures de contrôle plus élégantes. Shell est un langage de programmation, car il a: - des variables; - structures de contrôle (du type if); - sous-programmes (y compris les fichiers de commandes); - passer des paramètres; - interrompre la manipulation.

7.2. Fichier de démarrage de session (fichier de connexion)

Quelle que soit la version du Shell, une fois connecté à UNIX, il recherche un fichier de démarrage de session avec un nom prédéfini à exécuter en tant que fichier de commandes; - pour Versions UNIX 7 est: .profile; - pour C-Shell, ce sont: .login et / ou .cshrc. Les commandes suivantes sont généralement placées dans ce fichier: - réglage des caractéristiques du terminal; - notifications comme qui, date; - installation de répertoires de recherche de commandes (généralement: / bin, / usr / bin); - changer l'info-bulle de $ à un autre caractère, etc.

7.3. Procédure Shell

Ceci est un fichier batch. Il y a deux façons de l'appeler pour l'exécution: 1. $ sh dothat (où dothat est un fichier batch); 2. $ chmod 755 dothat (le rendre exécutable, c'est-à-dire -rwxr-xr-x) $ dothat. Vous devez connaître l'ordre de recherche des répertoires de commandes (par défaut): - courant; - système / bac; - système / usr / bin. Par conséquent, si le nom de votre fichier de commandes duplique le nom de la commande dans répertoires système, cette dernière deviendra indisponible (sauf si vous saisissez son nom complet).

7.4. Variables du shell

Dans Shell 7, une définition de variable contient un nom et une valeur: var \u003d valeur. La variable est accessible par son nom avec un $ devant: fruit \u003d apple (définition); echo $ fruit (accès); pomme (résultat d'écho). Donc, une variable est une chaîne. Concaténation de chaîne possible: $ fruit \u003d apple $ fruit \u003d pin $ fruit $ echo $ fruit ananas $ fruite \u003d apple $ wine \u003d $ (fruite) jack $ echo $ wine applejack $ D'autres moyens de définir la valeur d'une variable sont saisis à partir d'un fichier ou d'une sortie à partir d'une commande (voir section 7.6), ainsi que l'affectation de valeurs à une variable - un paramètre d'une boucle for à partir d'une liste de valeurs spécifiées explicitement ou par défaut (voir section 7.9). La variable peut être: 1) Une partie du nom de fichier complet: $ d / filename, où $ d est une variable (par exemple, d \u003d / usr / bin). 2) Dans le cadre d'une commande: $ S \u003d "sort + 2n + 1 - 2" (les espaces nécessitent des guillemets "") $ $ S tennis / lpr $ $ S basketball / lpr $ $ S pingpong / lpr $ Cependant, à l'intérieur de la valeur pour les commandes ne peuvent pas être des symboles |,\u003e,

7.5. Variables de shell prédéfinies

Certains d'entre eux sont en lecture seule. Les plus courants: HOME - répertoire "home" de l'utilisateur; sert d'argument par défaut pour cd; PATH est l'ensemble des répertoires dans lesquels UNIX recherche les commandes; PS1 - invite principale (chaîne) du système (pour v.7 - $). Le changement de PS1 (indice) est généralement effectué dans le fichier de connexion, par exemple: PS1 \u003d? ou PS1 \u003d "?" (avec un espace, ce qui est plus pratique). Changez PATH: $ echo $ PATH - voir; : / bin: / usr / bin - valeur PATH; $ cd - "maison"; $ mkdir bin - nouveau répertoire; $ echo $ HOME - regardez; / users / maryann est le répertoire courant; $ PATH \u003d: $ HOME / bin: $ PATH - change PATH; $ echo $ PATH - voir; : / users / maryann / bin: / bin: / usr / bin - nouvelle valeur PATH.

7.6. Définition de la variable Shell par sortie de commande

Exemple 1: $ now \u003d `date` (où`` sont des contre-coups) $ echo $ now dim 14 février 12:00:01 PST 1985 $ Exemple 2: (obtenir la valeur d'une variable à partir d'un fichier): $ menu \u003d `cat food` $ echo $ menu pommes cheddar chardonnay (remplacez les retours chariot par des espaces).

7.7. Variables de shell - Arguments de procédure

Il s'agit d'un type spécial de variable appelé nombres. Exemple: $ dothis raisins pommes poires (procédure). Ensuite, les paramètres de position (arguments) de cette commande sont disponibles par nom: $ 1 \u003d `raisins` $ 2 \u003d` pommes` $ 3 \u003d `poires` etc. jusqu'à 9 $. Cependant, il existe la commande shift, qui décale les noms du reste des arguments s'il y en a plus de 9 (largeur de la fenêtre 9). Une autre façon d'obtenir tous les arguments (même s'il y en a plus de 9): $ *, ce qui équivaut à $ 1 $ 2 ... Le nombre d'arguments est assigné à une autre variable: $ # (sharp). Enfin, le nom de la procédure est $ 0; la variable $ 0 n'est pas comptée lors du calcul de $ #.

7.8. Opérateurs de structure Shell

En plus des procédures, Shell a des opérateurs structurés comme "if-else" et "while-do". La programmation shell, en plus des procédures d'écriture, est utilisée pour: - élaborer l'algorithme avant de le coder en C ou FORTRAN-77 (pas de compilation, de liaison, de chargement, de débogage facile); - enseigner les principes de la programmation à des non-programmeurs.

7.9. Pour opérateur de boucle

Supposons que vous ayez un fichier batch makelist (procedure) $ cat makelist sort +1 -2 personnes | tr -d -9 | pr -h Distribution | lpr. Si au lieu d'un fichier, il y a plusieurs personnes, par exemple: administrateurs, personnes physiques, personnes logicielles, ..., alors vous devez répéter la procédure avec différents fichiers. Ceci est possible avec l'opérateur for. Syntaxe: for in do done Les mots-clés pour, do, done sont écrits depuis le début de la ligne. Exemple (procédure de changement makelist) pour le fichier dans adminpeople, hardpeople, softpeople do Trier +1 -2 $ file | tr ... | lpr fait. Vous pouvez utiliser des métacaractères Shell dans une liste de valeurs. Exemple: pour le fichier en * personnes (pour tous les noms se terminant par des personnes), faites ... terminé. Si in est omis, alors par défaut la liste des arguments de la procédure contenant la boucle est considérée comme la liste des valeurs, et si la boucle n'est pas dans une procédure, alors la liste des paramètres de ligne de commande (c'est-à-dire que la commande est utilisée comme procédure). Exemple: for file do ... done Pour appeler les administrateurs de makelist, les hardpeople softpeople feront de même.

7.10. Instruction if conditionnelle

Nous utilisons des noms de variables qui représentent les valeurs des paramètres de procédure: sort +1 -2 $ 1 | tr ... | lpr Un exemple d'appel invalide: makelist (aucun paramètre) où $ 1 n'est pas défini. L'erreur peut être corrigée en vérifiant le nombre d'arguments - la valeur de la variable $ # à l'aide de l'opérateur if -. Exemple: (procédure modifiée makelist): if test $ # -eq 0 then echo "Vous devez donner un nom de fichier" exit 1 else sort +1 -2 $ 1 | tr ... | lpr fi Ici, test et exit sont les commandes de test (voir section 7.11) et de sortie. Ainsi, la syntaxe de l'instruction if est: if; puis; Les mots-clés if, then, else et fi sont écrits depuis le début de la ligne. Une exécution réussie de la procédure signifie qu'elle renvoie true \u003d 0 (zéro) (échec - la valeur de retour n'est pas 0). L'instruction exit 1 définit la valeur de retour sur 1 pour une liste makelist ayant échoué et quitte la procédure. Emboîté si possible. L'abréviation else if elif, qui abrége simultanément fi.

7.11. Commande "Test"

Il ne fait pas partie de Shell, mais est utilisé dans les procédures Shell. Il existe trois types de contrôles: - l'évaluation des valeurs numériques; - évaluation du type de fichier; - évaluation des lignes. Chaque type a ses propres primitives (opérations op). Pour les nombres, la syntaxe est: N op M, où N, M sont des nombres ou des variables numériques; op prend les valeurs suivantes: -eq, -ne, gt, -lt, -ge, -le (avec la signification habituelle, comme dans FORTRAN). Pour un fichier, la syntaxe est: op filename, où op prend les valeurs suivantes: -s (le fichier existe et n'est pas vide); -f (fichier, pas répertoire); -d (fichier-répertoire (répertoire); -w (fichier à écrire); -r (fichier à lire). Pour les chaînes, la syntaxe est: S op R, où S, R sont des chaînes ou des variables de chaîne ou op1 S op prend des valeurs : \u003d (équivalence);! \u003d (non-équivalence); op1 prend les valeurs: -z (chaîne de longueur nulle) -n (chaîne de longueur non nulle) Enfin, plusieurs vérifications de types différents peuvent être combinées par des opérations logiques -a ( AND) et -o (OR) Exemples: $ if test -w $ 2 -a -r S1\u003e then cat $ 1 \u003e\u003e $ 2\u003e else echo "cannot append"\u003e fi $ Certaines saveurs UNIX utilisent test au lieu de crochets, c'est-à-dire si [...] au lieu de si test ....

7.12. Instruction de boucle While

Syntaxe: while do done Si la "commande" réussit, alors exécutez les "commandes", terminé mot-clé terminé. Exemple: if test $ # -eq 0 then echo "Usage: $ 0 file ..."\u003e & 2 exit fi while test $ # -gt 0 do if test -s $ 1 then echo "no file $ 1"\u003e & 2 else sort + 1 - 2 $ 1 | tr -d ... (procédures) fi shift (* renuméroter les arguments *) done Les procédures sont exécutées sur tous les arguments.

7.13. Jusqu'à l'opérateur de boucle

Inverse la condition de répétition par rapport à while Syntaxe: until do done Jusqu'à ce que la "commande" réussisse, exécutez les commandes qui se terminent par le mot done. Exemple: si test S # -eq 0 then echo "Usage $ 0 file ..."\u003e & 2 quitter fi jusqu'au test S # -eq 0 faire si test -s $ 1 puis echo "no file $ 1"\u003e & 2 sinon trier +1 - 2 $ 1 | tr -d ... (routine) fi shift (décalage d'argument) fait Comme ci-dessus.

7.14. Déclaration de sélection de cas

Syntaxe: case dans string1) ;; chaîne2) ;; chaîne3) ... etc. ... esac Exemple: Soit la procédure a une option -t qui peut être passée comme premier paramètre: ................. together \u003d no case $ 1 in -t) together \u003d yes décalage ;; -?) echo "$ 0: pas d'option $ 1" exit ;; esac si tester $ ensemble \u003d oui puis trier ... fi où? - métacaractère (si - ?, c'est-à-dire "une autre" option autre que -t, alors une erreur). Tous les métacaractères Shell peuvent être utilisés, y compris?, *, [-]. Il est facile d'ajouter (dans l'exemple) d'autres options simplement en étendant le cas.

7.15. Utilisation de fichiers temporaires dans le répertoire / tmp

Il s'agit d'un répertoire spécial dans lequel tous les fichiers peuvent être écrits pour tous les utilisateurs. Si une procédure de création d'un fichier temporaire est utilisée par plusieurs utilisateurs, il est alors nécessaire de s'assurer de l'unicité des noms fichiers générés... La pratique standard est le nom de fichier temporaire $ 0 $$, où $ 0 est le nom de la procédure et $$ est une variable standard qui équivaut à l'ID unique du processus exécutant la commande en cours. Bien que l'administrateur supprime périodiquement les fichiers temporaires dans / tmp, il est recommandé de les supprimer explicitement après utilisation.

7.16. Commentaires dans les procédures

Ils commencent par deux points :, qui est considéré comme une commande nulle, et le texte du commentaire est son argument. Pour empêcher Shell d'interpréter les métacaractères ($, *, etc.), il est recommandé de mettre le texte du commentaire entre guillemets simples. Sur certaines versions UNIX, une note commence par le signe #.

7.17. Exemple de procédure

: "Cette procédure fonctionne avec les fichiers contenant les noms": "et les numéros de téléphone,": "les trie ensemble ou séparément et imprime le résultat sur un écran": "ou une imprimante": "Touches de procédure:": "- t (ensemble) - fusionner et trier tous les fichiers ensemble ":" - p (imprimante) - imprimer les fichiers sur l'imprimante "if test $ # - eq 0 then echo" Usage: $ 0 file ... "\u003e & 2 exit fi together \u003d no print \u003d no while test $ # -gt 0 do case $ 1 in -t) ensemble \u003d yes shift ;; -p) print \u003d yes shift ;; -?) echo "$ 0: pas d'option $ 1" exit ;; *) si tester $ ensemble \u003d oui alors trier -u +1 -2 $ 1 | tr ...\u003e / tmp / $ 0 $$ if $ print \u003d no then cat / tmp / $ 0 $$ else lpr -c / tmp / $ 0 $$ fi rm / tmp / $ 0 $$ exit else if test -s $ 1 then echo "pas de fichier $ 1"\u003e & 2 autre tri +1 -2 $ 1 | tr ...\u003e / tmp / $ 0 $$ if $ print \u003d no then cat / tmp / $ 0 $$ else lpr -c / tmp / $ 0 $$ fi rm / tmp / $ 0 $$ fi shift fi ;; esac fait. La procédure vérifie le nombre de paramètres $ #, et s'il est égal à zéro, se termine. Sinon, il traite les paramètres (instruction case). Le paramètre peut être une clé (un caractère précédé d'un signe moins) ou un nom de fichier (une chaîne représentée par le métacaractère *). Si la clé n'est pas valide (le métacaractère? Est différent de t et p), la procédure se termine. Sinon, en fonction de la présence des touches t et p, les actions énoncées dans le commentaire au début de la procédure sont effectuées.

7.18. Traitement des interruptions dans les procédures

Si pendant l'exécution de la procédure un signal d'interruption est reçu (de la touche BREAK ou DEL, par exemple), alors tous les fichiers temporaires créés resteront impurs (jusqu'à ce que l'administrateur le fasse) en raison de l'arrêt immédiat du processus. La meilleure solution est la gestion des interruptions au sein de la procédure par l'opérateur trap: Syntaxe: trap signaux "arguments de commande" ... Les guillemets forment le premier argument de plusieurs commandes séparées par des points-virgules. Ils seront exécutés si une interruption se produit, indiquée par les arguments des signaux (entiers): 2 - lorsque vous interrompez le processus; 1 - si vous "accrochez" (déconnecté du système), etc. Exemple (développement du précédent): cas $ 1 dans ..... *) trap "rm / tmp / *; exit" 2 1 (suppression des fichiers temporaires) si test -s $ 1 .............. rm / tmp / * Ce serait mieux: trap "rm / tmp / *\u003e / dev / null; exit" 2 1 car l'interruption peut se produire avant comment le fichier / tmp / $ 0 $$ a été créé et une alerte pour ce cas est redirigée vers le périphérique nul.

7.19. Effectuer des opérations arithmétiques: expr

La commande expr évalue la valeur de l'expression fournie comme argument et envoie le résultat à la sortie standard. L'application la plus intéressante consiste à effectuer des opérations sur des variables Shell. Exemple de sommation de 3 nombres: $ cat sum3 expr $ 1 + $ 2 + $ 3 $ chmod 755 sum3 $ sum3 13 49 2 64 $ Exemple d'utilisation directe de la commande: $ expr 13 + 49 + 2 + 64 + 1129 $ Dans expr, les opérateurs arithmétiques suivants peuvent être utilisés - ry: +, -, *, /,% (reste). Tous les opérandes et opérations doivent être séparés par des espaces. Notez que le signe de multiplication doit être placé entre guillemets (simples ou doubles), par exemple: "*", car le caractère * a une signification particulière dans Shell. Exemple plus complexe d'expr dans une procédure (extrait de code): num \u003d "wc -l

7.20. Débogage des procédures Shell

Il existe trois outils disponibles pour vous aider à déboguer les procédures. 1) Placement dans le corps des commandes d'écho de procédure pour émettre des messages qui sont la trace de la procédure. 2) L'option -v (verbose \u003d verbose) de la commande Shell imprime la commande à l'écran avant de l'exécuter. 3) L'option -x (exécuter) dans la commande Shell provoque l'impression de la commande à l'écran lors de son exécution avec le remplacement de toutes les variables par leurs valeurs; c'est l'outil le plus puissant.

LA CLOCHE

Il y a ceux qui ont lu cette nouvelle avant vous.
Abonnez-vous pour recevoir les derniers articles.
Email
Nom
Nom de famille
Comment voulez-vous lire The Bell
Pas de spam