GNU/Linux >> Tutoriels Linux >  >> Linux

Astuces Bash plus stupides :variables, recherche, descripteurs de fichiers et opérations à distance

Ce billet de blog est le deuxième de deux couvrant quelques trucs et astuces pratiques pour tirer le meilleur parti du shell Bash. Dans la première partie, j'ai couvert l'histoire, le dernier argument, le travail avec des fichiers et des répertoires, la lecture de fichiers et les fonctions Bash. Dans ce segment, je couvre les variables shell, la recherche, les descripteurs de fichiers et les opérations à distance.

Utiliser des variables shell

Les variables Bash sont définies par le shell lorsqu'elles sont appelées. Pourquoi devrais-je utiliser hostname quand je peux utiliser $HOSTNAME, ou pourquoi devrais-je utiliser whoami quand puis-je utiliser $USER ? Les variables bash sont très rapides et ne nécessitent pas d'applications externes.

Voici quelques variables fréquemment utilisées :

$PATH
$HOME
$USER
$HOSTNAME
$PS1
..
$PS4

Utilisez le echo commande pour développer les variables. Par exemple, la variable shell $PATH peut être étendue en exécutant :

$> echo $PATH

[ Télécharger maintenant :Un guide de l'administrateur système sur les scripts Bash. ]

Utilisez la commande de recherche

Le find La commande est probablement l'un des outils les plus utilisés dans le système d'exploitation Linux. Il est extrêmement utile dans les shells interactifs. Il est également utilisé dans les scripts. Avec find Je peux répertorier les fichiers plus anciens ou plus récents qu'une date spécifique, les supprimer en fonction de cette date, modifier les autorisations des fichiers ou des répertoires, etc.

Familiarisons-nous avec cette commande.

Pour lister les fichiers de plus de 30 jours, je lance simplement :

$> find /tmp -type f -mtime +30

Pour supprimer des fichiers de plus de 30 jours, exécutez :

$> find /tmp -type f -mtime +30 -exec rm -rf {} \;

ou

$> find /tmp -type f -mtime +30 -exec rm -rf {} +

Bien que les commandes ci-dessus suppriment les fichiers de plus de 30 jours, telles qu'elles sont écrites, elles fork le rm commande chaque fois qu'ils trouvent un fichier. Cette recherche peut être écrite plus efficacement en utilisant xargs :

$> find /tmp -name '*.tmp' -exec printf '%s\0' {} \; | xargs -0 rm

Je peux utiliser find pour lister sha256sum fichiers uniquement en exécutant :

$> find . -type f -exec sha256sum {} +

Et maintenant, pour rechercher et supprimer les fichiers .jpg en double :

$> find . -type f -name '*.jpg' -exec sha256sum {} + | sort -uk1,1 

Descripteurs de fichiers de référence

Dans le shell Bash, les descripteurs de fichiers (FD) sont importants pour gérer l'entrée et la sortie des commandes. De nombreuses personnes ont des problèmes pour comprendre correctement les descripteurs de fichiers. Chaque processus a trois descripteurs de fichier par défaut, à savoir :

Code Signification Emplacement Description
0 Saisie standard /dev/stdin Clavier, fichier ou un flux
1 Sortie standard /dev/stdout Moniteur, terminal, affichage
2 Erreur type /dev/stderr Les codes de sortie non nuls sont généralement>FD2, display

Maintenant que vous savez ce que font les FD par défaut, voyons-les en action. Je commence par créer un répertoire nommé foo , qui contient file1 .

$> ls foo/ bar/
ls: cannot access 'bar/': No such file or directory
foo/:
file1

La sortie Aucun fichier ou répertoire de ce type passe à l'erreur standard (stderr) et s'affiche également à l'écran. Je vais exécuter la même commande, mais cette fois, utilisez 2> pour omettre stderr :

$> ls foo/ bar/ 2>/dev/null
foo/:
file1

Il est possible d'envoyer la sortie de foo à la sortie standard (stdout) et à un fichier simultanément, et ignorez stderr. Par exemple :

$> { ls foo bar | tee -a ls_out_file ;} 2>/dev/null
foo:
file1

Ensuite :

$> cat ls_out_file
foo:
file1

La commande suivante envoie stdout à un fichier et stderr à /dev/null afin que l'erreur ne s'affiche pas à l'écran :

$> ls foo/ bar/ >to_stdout 2>/dev/null
$> cat to_stdout
foo/:
file1

La commande suivante envoie stdout et stderr au même fichier :

$> ls foo/ bar/ >mixed_output 2>&1
$> cat mixed_output
ls: cannot access 'bar/': No such file or directory
foo/:
file1

C'est ce qui s'est passé dans le dernier exemple, où stdout et stderr ont été redirigés vers le même fichier :

    ls foo/ bar/ >mixed_output 2>&1
             |          |
             |          Redirect stderr to where stdout is sent
             |                                                        
             stdout is sent to mixed_output

Une autre petite astuce (> Bash 4.4) pour envoyer à la fois stdout et stderr dans le même fichier utilise le signe esperluette. Par exemple :

$> ls foo/ bar/ &>mixed_output

Voici une redirection plus complexe :

exec 3>&1 >write_to_file; echo "Hello World"; exec 1>&3 3>&-

Voici ce qui se passe :

  • exec 3>&1                      Copier stdout dans le descripteur de fichier 3
  • > write_to_file              Faites FD 1 pour écrire dans le fichier
  • echo "Hello World"     Aller au fichier car FD 1 pointe maintenant vers le fichier
  • exec 1>&3                      Copier FD 3 vers 1 (swap)
  • Trois>&-                       Fermer le descripteur de fichier trois (nous n'en avons plus besoin)

Il est souvent pratique de regrouper les commandes, puis d'envoyer la sortie standard vers un seul fichier. Par exemple :

$> { ls non_existing_dir; non_existing_command; echo "Hello world"; } 2> to_stderr
Hello world

Comme vous pouvez le voir, seul "Hello world" est imprimé à l'écran, mais la sortie des commandes ayant échoué est écrite dans le fichier to_stderr.

Exécuter des opérations à distance

J'utilise Telnet, netcat, Nmap et d'autres outils pour tester si un service distant est opérationnel et si je peux m'y connecter. Ces outils sont pratiques, mais ils ne sont pas installés par défaut sur tous les systèmes.

Heureusement, il existe un moyen simple de tester une connexion sans utiliser d'outils externes. Pour voir si un serveur distant exécute un site Web, une base de données, SSH ou tout autre service, exécutez :

$> timeout 3 bash -c ‘</dev/tcp/remote_server/remote_port’ || echo “Failed to connect”

Par exemple, pour voir si serveurA exécute le service MariaDB :

$> timeout 3 bash -c ‘</dev/tcp/serverA/3306’ || echo “Failed to connect”

Si la connexion échoue, le message Échec de la connexion message s'affiche sur votre écran.

Supposons que serveurA est derrière un pare-feu/NAT. Je veux voir si le pare-feu est configuré pour autoriser une connexion de base de données à serveurA , mais je n'ai pas encore installé de serveur de base de données. Pour émuler un port de base de données (ou tout autre port), je peux utiliser ce qui suit :

[serverA ~]# nc -l 3306

Sur clientA , exécutez :

[clientA ~]# timeout 3 bash -c ‘</dev/tcp/serverA/3306’ || echo “Failed”

Pendant que je parle de connexions à distance, qu'en est-il de l'exécution de commandes sur un serveur distant via SSH ? Je peux utiliser la commande suivante :

$> ssh remotehost <<EOF  # Press the Enter key here
> ls /etc
EOF

Cette commande exécute ls /etc sur l'hôte distant.

Je peux également exécuter un script local sur l'hôte distant sans avoir à copier le script sur le serveur distant. Une façon est d'entrer :

$> ssh remote_host 'bash -s' < local_script

Un autre exemple consiste à transmettre localement des variables d'environnement au serveur distant et à mettre fin à la session après l'exécution.

$> exec ssh remote_host ARG1=FOO ARG2=BAR 'bash -s' <<'EOF'
> printf %s\\n "$ARG1" "$ARG2"
> EOF
Password:
FOO
BAR
Connection to remote_host closed.

Il existe de nombreuses autres actions complexes que je peux effectuer sur l'hôte distant.

Récapitulez

Il y a certainement plus à Bash que ce que j'ai pu couvrir dans ce billet de blog en deux parties. Je partage ce que je sais et ce que je vis au quotidien. L'idée est de vous familiariser avec quelques techniques qui pourraient rendre votre travail moins sujet aux erreurs et plus amusant.

[ Vous voulez tester vos compétences d'administrateur système ? Faites une évaluation des compétences aujourd'hui. ]


Linux
  1. Bash :Utilisation procédurale sécurisée des espaces blancs de la recherche dans la sélection ?

  2. Expansion et variables des accolades Bash ?

  3. Comment trouver le type d'un fichier Img et le monter ?

  4. Rechercher un fichier avec les commandes Rechercher et Localiser sous Linux

  5. Trucs et astuces Linux .htaccess

Rechercher et supprimer le fichier le plus ancien s'il y a plus de X fichiers dans un répertoire sous Linux

Plugins Geany utiles, trucs et astuces

Comment utiliser Sed pour rechercher et remplacer une chaîne dans un fichier

Modifier de manière récursive les extensions de fichier dans Bash

rechercher et supprimer un fichier ou un dossier de plus de x jours

Effectuer des opérations d'écriture atomique dans un fichier en bash