
Utilisez-vous la coque tous les jours? Prêt à résoudre certains problèmes logiques et à apprendre quelque chose de nouveau? Bienvenue au chat.
Certaines des tâches présentées ici n'apporteront pas de réels avantages, car elles affectent certains cas limites complexes. L'autre partie sera utile à ceux qui utilisent constamment le shell et lisent les scripts des autres.
Remarque: au moment de la rédaction, l'auteur a utilisé bash 4.4.12 (1) -release dans le sous-système Linux sur Windows 10. La complexité des tâches est différente.
Flux d'entrée / sortie
Tâche 1$ cat 1 The cake is a lie! Wanted! Cake or alive $ cat 1 | head | tail | sed -e 's/alive/dead/g' | tee | wc -l > 1
Combien de lignes seront dans le fichier 1 après la commande?
ExplicationAprès avoir interprété la commande, mais avant d'exécuter tous les programmes, bash fonctionne avec les flux d'entrée / sortie spécifiés. Ainsi, le fichier 1
est effacé avant de démarrer le premier programme et cat
ouvre le fichier déjà effacé.
Tâche 2 $ cat file1 I love UNIX! $ cat file2 I don't like UNIX $ cat file1 <file2
Qu'est-ce qui sera affiché à l'écran?
ExplicationCertains programmes martèlent stdin lorsque des fichiers sont spécifiés.
Tâche 3 $ cat file Just for fun $ cat file 1>&2 2>/dev/null
Qu'est-ce qui sera affiché à l'écran?
ExplicationIl existe une idée fausse selon laquelle la séquence
1>&2
redirige le premier thread vers le second, mais ce n'est pas le cas. Considérez l'équipe de la mission. Au début de l'interprétation de la commande entrée, la table de flux ressemble à ceci:
bash détecte la séquence
1>&2
et copie le contenu de la cellule 2 dans la cellule 1:
Après avoir détecté la séquence
2>/dev/null
interpréteur écrit la valeur dans la cellule 2, en laissant les autres cellules intactes:
0 | 1 | 2 |
stdin | stderr | / dev / null |
bash affiche également un flux d'erreurs, afin que nous trouvions le texte du fichier à l'écran.
Tâche 4Comment envoyer la sortie stdout à stderr, et la sortie stderr, au contraire, à stdout?
La réponse4>&1 1>&2 2>&4
ExplicationLe principe est exactement le même que dans la tâche précédente. C'est pourquoi nous avons besoin d'un flux supplémentaire pour le stockage temporaire.
Exécutables
Tâche 5Compte tenu du fichier test.sh
Les commandes suivantes sont exécutées:
$ ls 1 2 3 test.sh $ ./test.sh 1 2 3
Que produira le script?
La réponse1 2 3
1 2 3
ls: cannot access '1 2 3': No such file or directory
1 2 3
ExplicationSans guillemets, les variables $ * et $ @ ne sont pas différentes et sont développées dans tous les arguments positionnels donnés du script, séparés par un espace. Entre guillemets, la méthode de divulgation change: $ * devient "$ 1 $ 2 $ 3" ​​et $ @ à son tour "$ 1" "$ 2" "$ 3". Le fichier «1 2 3» ne se trouvant pas dans le répertoire, ls affiche une erreur
Tâche 6Dans le répertoire actuel, créez un fichier
-c
avec les autorisations de 755 et le contenu suivant:
Remettez à zéro la variable $ PATH et essayez d'exécuter:
$ PATH= $ -c "echo SURPRISE"
Qu'est-ce qui sera affiché à l'écran? Que se passe-t-il si vous ressaisissez la dernière commande?
La réponseLa première fois sera affichée SURPRISE
, la deuxième fois echo SURPRISE
ExplicationSi PATH est vide, le shell commence à rechercher des fichiers dans le répertoire courant. -c est juste situé. Le fichier exécutable étant un fichier texte, la première ligne est lue sur le sujet de shebang. L'équipe est constituée selon le modèle:
<shebang> <filename> <args>
Ainsi, avant exécution, notre commande ressemble à ceci:
/bin/bash -c "echo SURPRISE"
Et, par conséquent, ce n'est absolument pas ce que nous voulions faire.
Si vous l'exécutez une deuxième fois, le shell récupérera des informations sur -c dans le cache et l'exécutera déjà correctement. La seule façon de vous protéger d'un tel effet inattendu est d'ajouter deux inconvénients au shebang.
Variables
Tâche 7 $ ls file $ cat <$(ls) $ cat <(ls)
Qu'est-ce qui sera affiché dans le premier et le deuxième cas?
La réponseLe premier affichera le contenu du fichier, le second - le nom du fichier.
ExplicationDans le premier cas, la substitution est effectuée
cat <file
Dans le second cas,
<(ls)
sera remplacé par un canal nommé connecté par l'entrée à stdout ls et la sortie de stdin cat.
Après substitution, la commande prendra la forme:
cat /dev/fd/xx
Tâche 8 $ TEST=123456 $ echo ${TEST%56}
Qu'est-ce qui sera affiché à l'écran?
ExplicationAvec un tel enregistrement, le modèle correspond (# - depuis le début de la variable; ## - avec avidité depuis le début de la variable;% - depuis la fin de la variable; %% - avec avidité depuis la fin de la variable) et est supprimé lors de la substitution. Le contenu de la variable reste intact. Ainsi, par exemple, il est pratique d'obtenir le nom de fichier sans l'extension.
$ TEST=file.ext $ echo ${TEST%.ext} file
Tâche 9 $ echo ${friendship:-magic}
Qu'est-ce qui sera affiché à l'écran?
La réponseSi la variable d'amitié est définie, alors le contenu de la variable. Sinon, la magie.
ExplicationDans la documentation, cette magie est appelée "non définie ou nulle" et vous permet d'utiliser la valeur par défaut spécifiée d'une variable sur une seule ligne.
Ordre d'exécution
Tâche 10 while true; false; do echo Success done
Qu'est-ce qui sera affiché à l'écran?
ExplicationLes instructions while et if vous permettent de placer une séquence entière d'actions dans la condition, mais le résultat (code retour) ne sera pris en compte que dans la dernière commande. Comme c'est faux, la boucle ne commencera même pas.
Tâche 11 $ false && true || true && false && echo 1 || echo 2
Qu'est-ce qui sera affiché à l'écran?
ExplicationAjoutez des parenthèses pour un ordre explicite et simplifiez la commande, en tenant compte du fait que seul le code retour de la dernière commande est pris en compte:
((((false && true) || true) && false) && echo 1) || echo 2 (((false || true) && false) && echo 1) || echo 2 ((true && false) && echo 1) || echo 2 (false && echo 1) || echo 2 false || echo 2 echo 2
Les commentaires, suggestions et tâches supplémentaires sont les bienvenus dans les commentaires ou les MP.