Donc, je ne connais pas grand chose à propos de bash et j'ai besoin de l'aide d'un professionnel. J'essaye de lancer un script comme celui-ci:
filename='file1'
while read p; do
ssh -p 2222 $p 'who -b' | awk '{print $(NF-1)" "$NF}' >> file2*
ce que j'essaie de faire est un script qui passe en revue toutes les adresses de fichier1 pour voir quand elles ont été redémarrées pour la dernière fois, puis la réponse dans fichier2.
Le problème, c'est qu'il ne s'agit que de la première adresse et non de l'autre.
La première adresse a reçu un mot de passe que je dois taper pour poursuivre le processus. Peut-être que ce soit le problème ou est-ce que je spécifie chaque ligne de fichier1 ou est-ce que je me trompe complètement au début?
Enfin, j'ai supposé que la partie restante du script est correcte. Puis j'ai suivi commentaire de @ dessert et utilisé shellcheck
qui m'a amené au problème et à sa solution:
SC2095 : Ajoutez _
< /dev/null
_ pour empêcher ssh d’avaler stdin.
Donc, vous devez changer votre script de cette façon:
_ssh -p 2222 "$p" 'who -b' < /dev/null | awk '{print $(NF-1)" "$NF}' >> 'file2'
_
Selon le réponse originale et grâce aux conseils utiles fournis dans les commentaires par @ EliahKagan et @ rexkogitans , le script complet pourrait ressembler à cette:
_#!/bin/bash
# Collect the user's input, and if it`s empty set the default values
[[ -z "${1}" ]] && OUT_FILE="reboot-indication.txt" || OUT_FILE="$1"
[[ -z "${2}" ]] && IN_FILE="hosts.txt" || IN_FILE="$2"
while IFS= read -r Host; do
indication="$(ssh -n "$Host" 'LANG=C who -b' | awk '{print $(NF-1)" "$NF}')"
printf '%-14s %s\n' "$Host" "$indication" >> "$OUT_FILE"
done < "$IN_FILE"
_
_< /dev/null/
_ est remplacé par l'option _-n
_ de la commande ssh
. De man ssh
:
_-n Redirects stdin from /dev/null (actually, prevents reading from stdin).
This must be used when ssh is run in the background... This does not work
if ssh needs to ask for a password or passphrase; see also the -f option.
_
_IFS= read -r line
_ - comme le dit @ StéphaneChazelas dans sa réponse encyclopédique - est le moyen canonique de lire une ligne d'entrée avec le read
intégré.
La clé est que read
lit les mots d'une ligne (éventuellement des barres obliques inversées), où les mots sont délimités par _$IFS
_ et la barre oblique inverse peut être utilisée pour échapper aux délimiteurs (ou lignes suivantes). La commande read
doit être modifiée pour lire les lignes.
_IFS=
_ change le séparateur de champ interne en chaîne nulle , nous conservons donc les espaces de début et de fin dans le résultat.
L'option _-r
_ - r entrée aw - désactive l'interprétation des échappements de barre oblique inversée et la poursuite de la ligne dans les données lues ( - référence ).
_printf '%s %s' "$VAR1" "$VAR2"
_ fournira un meilleur format de sortie ( référence ).
_LANG=C
_ garantira une sortie identique de _who -b
_ sur chaque serveur, ainsi l'analyse de la sortie avec awk
sera également garantie.
Remarque: supposons qu'il existe un fichier _~/.ssh/config
_ et que des paramètres supplémentaires tels que _-p 2222
_ ne sont pas nécessaires ( ---] [référence ).
Appelez le script ci-dessus _ssh-check.sh
_ (n'oubliez pas de _chmod +x
_) et utilisez-le de cette façon:
Utilisez les valeurs par défaut des fichiers d'entrée (hosts.txt) et du fichier de sortie (reboot-indication.txt):
_./ssh-check.sh
_
Définir une valeur personnalisée pour le fichier de sortie; définir une valeur personnalisée également pour les fichiers d'entrée:
_./ssh-check.sh 'my-custom.out'
./ssh-check.sh 'my-custom.out' 'my-custom.in'
_
Lire cette réponse pour voir comment toute l'approche pourrait être améliorée.
Vous avez oublié de fermer la boucle while-do. Ajoutez done
à la fin.
filename='file1'
while read p; do
ssh -p 2222 $p 'who -b' | awk '{print $(NF-1)" "$NF}' >> file2*
done