Sous-sheells Linux avancés avec des exemples

Sous-sheells Linux avancés avec des exemples

Si vous lisez nos précédents sous-coquilles Linux pour les débutants avec des exemples d'article, ou si vous êtes déjà expérimenté avec des sous-coquilles, vous savez que les sous-coquilles sont un moyen puissant de manipuler les commandes de bash en ligne et de manière contextuelle.

Dans ce tutoriel, vous apprendrez:

  • Comment créer des commandes de sous-coque plus avancées
  • Où vous pouvez utiliser des sous-coquilles plus avancées dans votre propre code
  • Exemples de commandes de sous-shell plus avancées
Sous-sheells Linux avancés avec des exemples

Exigences et conventions logicielles utilisées

Exigences logicielles et conventions de ligne de commande Linux
Catégorie Exigences, conventions ou version logicielle utilisée
Système Indépendant de la distribution Linux
Logiciel Ligne de commande bash, système basé sur Linux
Autre Toute utilité qui n'est pas incluse dans le shell bash par défaut peut être installée en utilisant Sudo Apt-Get Install Utility-Name (ou yum au lieu de Apt-get)
Conventions # - nécessite que les commandes Linux soient exécutées avec des privilèges racine soit directement en tant qu'utilisateur racine, soit par l'utilisation de Sudo commande
$ - exige que les commandes Linux soient exécutées en tant qu'utilisateur régulier non privilégié

Exemple 1: Compter les fichiers

$ if [$ (ls [a-z] * 2> / dev / null | wc -l) -gt 0]; puis écho "a trouvé une ou plusieurs occurrences de fichiers [a-z] *!"; Fi 


Ici, nous avons un si Déclaration avec As It First Comparison Value A Subshell. Cela fonctionne bien et offre une grande flexibilité en matière d'écriture si affirmations. Il est différent alors que le fonctionnement binaire (vrai ou faux) comme par exemple un Si grep -q 'search_term' ./ docfile.SMS déclaration. Il est plutôt évalué en soi comme comparaison standard (apparié avec le plus grand-zéro -gt 0 clause).

La sous-coffre essaie de répertorier les fichiers de répertoire nommés [a-z] *, je.e. les fichiers commençant par au moins une lettre dans le A-Z gamme, suivie de tout caractère ultérieur. Il est sécurisé en ajoutant 2> / dev / null - je.e. Toute erreur affichée (sur stderr - la sortie d'erreur standard, signifiée par le 2) sera redirigé > pour / dev / null - je.e. le dispositif nul Linux - et donc ignoré.

Enfin, nous passons l'entrée LS à wc -l Ce qui comptera pour nous combien de lignes (ou dans ce cas, des fichiers) ont été vus. Si le résultat était supérieur à 0, la note informative est affichée.

Notez comment le contexte dans lequel le sous-coquille fonctionne varie. Premièrement, dans ce cas, la sous-coquille fonctionne à l'intérieur du répertoire de travail actuel (i.e. $ Pwd) ce qui est notamment la valeur par défaut je.e. Les sous-coquilles par défaut commencent par leur propre environnement PWD réglé sur le répertoire de travail actuel. Deuxièmement, la sous-coquille fonctionne dans le contexte d'un si déclaration.

Aucune sortie n'est générée par cette commande, car elle est exécutée dans un répertoire vide. Cependant, notez que le fait qu'aucune sortie n'est générée signifie également que notre suppression d'erreur fonctionne. Voyons que:

$ if [$ (ls [a-z] * | wc -l) -gt 0]; puis écho "a trouvé une ou plusieurs occurrences de fichiers [a-z] *!"; fi ls: ne peut pas accéder à '[a-z] *': aucun fichier ou répertoire de ce type 

Nous pouvons voir comment la suppression de la suppression des erreurs a fonctionné dans l'exemple précédent. Créons ensuite un fichier et voyons comment fonctionne notre one-liner:

$ touchez un $ si [$ (ls [a-z] * 2> / dev / null | wc -l) -gt 0]; puis écho "a trouvé une ou plusieurs occurrences de fichiers [a-z] *!"; fi a trouvé une ou plusieurs occurrences de fichiers [a-z] *! 


Super, il semble que notre script unique fonctionne bien. Ajoutons ensuite un fichier secondaire et voyons si nous pouvons améliorer le message

$ touch b $ if [$ (ls [a-z] * 2> / dev / null | wc -l) -gt 0]; puis écho "a trouvé une ou plusieurs occurrences de fichiers [a-z] *!"; fi a trouvé une ou plusieurs occurrences de fichiers [a-z] *! $ if [$ (ls [a-z] * 2> / dev / null | wc -l) -gt 0]; puis écho "trouvé exactement $ (ls [a-z] * 2> / dev / null | wc -l) occurrences de fichiers [a-z] *!"; Fi a trouvé exactement 2 occurrences de fichiers [a-z] *! 

Nous voyons ici que l'ajout d'un deuxième fichier (par toucher b) ne fait aucune différence (comme on le voit dans le premier si Commande), sauf si nous modifions la sortie pour signaler réellement le nombre de fichiers trouvés en insérant une sous-coquille secondaire dans la sortie.

Ceci n'est cependant pas codé de manière optimale; Dans ce cas, deux sous-coquilles nécessitent une exécution (le coût d'une création de sous-coquilles est très minime, mais si vous avez de nombreuses sous-coquilles créées en fréquence élevée, le coût est important), et que la liste directe est demandée deux fois (générant des E / S supplémentaires et Ralentissant notre code à la vitesse du sous-système d'E / S et du type de disque utilisé). Mettons cela dans une variable:

$ Count = "$ (ls [a-z] * 2> / dev / null | wc -l)"; si [$ count -gt 0]; puis écho "trouvé exactement $ count occurrences de fichiers [a-z] *!"; Fi a trouvé exactement 2 occurrences de fichiers [a-z] *! 

Super. Il s'agit d'un code plus optimal; Une seule sous-coquille est utilisée et le résultat est stocké dans une variable qui est ensuite utilisée deux fois, et une seule récupération de répertoire de disque est nécessaire. Notez également que cette solution peut être plus thread-safe.

Par exemple, dans le si Énoncé qui avait deux sous-coquilles, si dans le temps entre l'exécution de ces sous-coquilles, un troisième fichier était créé, le résultat peut ressembler à ceci: Trouvé exactement 3 occurrences de fichiers [a-z] *! Alors que le premier si déclaration (en utilisant la première sous-coquille) vraiment qualifiée sur Si 2 -gt 0 - je.e. 2. Cela ferait peu de différence dans ce cas, mais vous pouvez voir comment, dans un codage, cela peut devenir très important à surveiller.

Exemple 2: sous-coquilles de calcul

$ touch z $ echo $ [$ (date +% s) - $ (stat -c% z ./ z)] 1 $ echo $ [$ (date +% s) - $ (stat -c% z ./ z)] 5 

Ici, nous avons créé un fichier, à savoir z, et a ensuite découvert l'âge du fichier en quelques secondes en utilisant la deuxième commande. Quelques secondes plus tard, nous avons à nouveau exécuté la commande et nous pouvons voir que le fichier a maintenant 5 secondes.

Le Date +% S La commande nous donne l'heure actuelle en quelques secondes depuis Epoch (1970-01-01 UTC), et stat -c% z nous donne les secondes depuis l'époque pour le fichier qui a été précédemment créé, et maintenant référencé ici ./ z, Donc, tout ce que nous devons par la suite, c'est de soustraire ces deux. Nous plaçons le Date +% S Tout d'abord, c'est le nombre le plus élevé (l'heure actuelle) et ainsi calculer correctement le décalage en secondes.

Le -c option de stat indique simplement que nous voulons une mise en forme de sortie particulière, dans ce cas % Z, ou en d'autres termes le temps depuis l'époque. Pour date La syntaxe pour la même idée est +% s, bien qu'en relation avec l'heure actuelle et non liée à un fichier particulier.

Exemple 3: Sous-coquilles à l'intérieur de SED et d'autres outils

$ echo '0'> a $ sed -i "s | 0 | $ (whoami) |" ./ a $ chat a roel 


Comme vous pouvez le voir, nous pouvons utiliser une sous-coquille dans presque toutes les commandes que nous exécutons sur la ligne de commande.

Dans ce cas, nous créons un fichier un avec comme contenu 0 et par la suite en ligne remplacer le 0 pour $ (whoami) qui, lorsque la sous-coquille sera exécutée au fur et à mesure que la commande est analysée, se substituera au nom d'utilisateur roel. Faites attention à ne pas utiliser de devis uniques car cela rendra le sous-coque inactif car la chaîne sera interprétée comme du texte littéral:

$ echo '0'> a $ sed -i's | 0 | $ (whoami) | ' ./ a $ chat a $ (whoami) 

Notez ici que le sed Syntaxe activée (S | 0 |… |) fonctionne toujours correctement (!), tandis que la fonctionnalité de sous-coquille bash $ () n'a pas!

Exemple 4: Utilisation d'évaluation et de boucle pour

$ LOOPS = 3 $ echo 1… $ LOOPS 1… 3 $ EVAL ECHO 1… $ LOOPS 1 2 3 $ pour i dans $ (echo 1… $ Loops); faire écho "$ i"; fait 1… 3 $ pour i dans $ (eval echo 1… $ Loops); faire écho "$ i"; fait 1 2 3 

Cet exemple, bien que ce n'est pas le moyen optimal d'effectuer un simple pour Loop, nous montre quelques façons d'intégrer les sous-coquilles même à l'intérieur des boucles. Nous utilisons le évaluer déclaration pour traiter le 1… 3 texte en 1 2 3 qui peut ensuite être utilisé directement à l'intérieur du pour clause de répétition de boucle.

Parfois, l'utilisation de sous-coquilles et la fourniture d'informations en ligne dans le contexte via les sous-coquilles n'est pas toujours évidente, et peut nécessiter des tests, des ajustements et des réglages fins avant que les sous-coquilles ne s'exécutent comme prévu. C'est normal et très conforme au codage de bash normal.

Conclusion

Dans cet article, nous avons exploré quelques exemples plus approfondis et avancés d'utilisation des sous-coquilles en bash. La puissance des sous-coquilles vous permettra de transformer la plupart des scripts à une ligne en versions beaucoup plus puissantes, sans parler de la possibilité de les utiliser à l'intérieur de vos scripts. Lorsque vous commencez à explorer les sous-coquilles et que vous trouvez de belles façons de les utiliser, veuillez les publier ci-dessous dans les commentaires!

Apprécier!

Tutoriels Linux connexes:

  • Choses à installer sur Ubuntu 20.04
  • Choses à faire après l'installation d'Ubuntu 20.04 Focal Fossa Linux
  • Sous-coquilles Linux pour les débutants avec des exemples
  • Une introduction à l'automatisation Linux, des outils et des techniques
  • Comment utiliser des sous-coquilles bash à l'intérieur des instructions IF
  • Choses à faire après l'installation d'Ubuntu 22.04 Jammy Jellyfish…
  • Commandes Linux: les 20 meilleures commandes les plus importantes que vous devez…
  • Commandes Linux de base
  • Téléchargement Linux
  • Installez Arch Linux dans VMware Workstation