Je voudrais prendre la sortie de deux commandes -
zpool list
zfs list
et pour chaque piscine trouvée:
zpool get all nameofpool
et pour chaque système de fichiers trouvé:
zfs get all nameoffilesystem
Contexte et environnement
Je fais des changements locaux au script qui fait partie intégrante d'OS X,
/usr/bin/sysdiagnose
#!/bin/sh
pour commencer- toujours exécuté avec les privilèges de superutilisateur
- parfois efficacement sans tête ( déclenché par un accord de clé ), le résultat doit donc être un fichier.
Première expérience
D'après l'exemple de # 65, supprimez tous les instantanés ZFS :
#!/bin/sh
for dataset in `zfs list -H | cut -f 1`
do
zfs get all $dataset
done
Cela fonctionne, mais pas là où il y a un espace dans le nom du jeu de données. Par exemple, où le système de fichiers est zhandy/Pocket Time Machine
la sortie comprend:
cannot open 'zhandy/Pocket': dataset does not exist
cannot open 'Time': dataset does not exist
cannot open 'Machine': dataset does not exist
Deuxième expérience
… Était basé sur la première réponse à cette question - utiliser IFS
- et rendait le script plus semblable à celui d'Apple. Voir révision 4 .
Troisième expérience
Basé sur la réponse acceptée à cette question - avec IFS
, et guillemets pour "$dataset"
:
#!/bin/sh
data_directory_path=~/Desktop
ECHO=/bin/echo
ZFS=/usr/sbin/zfs
ZPOOL=/usr/sbin/zpool
# If there exists a zfs binary, get some ZFS information
if [ -f "${ZFS}" ]
then
"${ECHO}" "Recording ZFS pool version information ..."
"${ZPOOL}" upgrade &> ${data_directory_path}/zpool\ upgrade.txt
"${ECHO}" " listing all ZFS pools ..."
"${ZPOOL}" list &> ${data_directory_path}/zpool\ list.txt
"${ECHO}" " detailed health status and verbose data error information ..."
"${ZPOOL}" status -v &> ${data_directory_path}/zpool\ status.txt
"${ECHO}" " pools that are available but not currently imported"
"${ZPOOL}" import &> ${data_directory_path}/zpool\ import.txt
"${ECHO}" "Recording ZFS file system version information ..."
"${ZFS}" upgrade &> ${data_directory_path}/zfs\ upgrade.txt
"${ECHO}" " listing all ZFS file systems ..."
"${ZFS}" list &> ${data_directory_path}/zfs\ list.txt
"${ECHO}" " all properties of each file system"
OLD_IFS=$IFS
IFS=$'\n'
for dataset in `zfs list -H | cut -f 1`
do
"${ZFS}" get all "$dataset" &> ${data_directory_path}/ZFS\ file\ system\ properties.txt
done
IFS=$OLD_IFS
"${ECHO}" "Listing the contents of /dev/dsk"
"${LS}" -@adel /Volumes &> ${data_directory_path}/ls-dev-dsk.txt
"${ECHO}" "Listing the contents of /var/zfs/dsk"
"${LS}" -@adel /Volumes &> ${data_directory_path}/ls-var-zfs-dsk.txt
fi
Parmi les fichiers résultants, ZFS file system properties.txt
répertorie les propriétés d'un seul système de fichiers ZFS: un jeu de données avec un espace dans son nom.
Le résultat final le plus souhaitable est les propriétés:
- pour tous les systèmes de fichiers ZFS
- dans un fichier.
Supprimer la chaîne suivante -
&> ${data_directory_path}/ZFS\ file\ system\ properties.txt
- obtient les propriétés de tous les systèmes de fichiers ZFS, dans une fenêtre de Terminal mais pas dans un fichier. Cela me suffit pour accepter une réponse.
Le critère de sortie dans un fichier , qui ne figurait pas dans ma première édition de la question, peut être facilement répondu ailleurs.
la source
>>
(non&>
ou&>>
). Dans les commentaires adressés à Apple, j'ai demandésysdiagnose
à être ajouté à Apple Open Source . Si cela se produit, je rendrai publiques mes autres modifications apportées au script, dont la plupart ne sont pas liées à ZFS.for DS in $(zfs list -H -o name); do zfs get all "$DS"; done
? Cela fait un moment que j'utilise cet idiome dans mes propres scripts et j'espère n'avoir rien oublié (notez l'utilisation de-o name
and-"
quoting pour limiter la sortie (dont vous n'avez plus besoincut
) et gérer les espaces dans les noms de jeu de données (même si espace est supposé être un caractère invalide pour les noms de jeu de données)Réponses:
Ne pas diviser en espaces
La
for
boucle de bash divise l'argument par défaut pour tous les caractères d'espacement. Vous pouvez en quelque sorte échapper à chaque ligne - ou simplement basculer vers un autre caractère de délimitation.cut
retournera une valeur par ligne, donc il y a une nouvelle ligne entre nous que nous pouvons choisir.Faites attention aux doubles guillemets
zfs get all
, afin que chacun$dataset
ne soit pas divisé non plus.Réinitialisation IFS
Ensuite, vous voudrez peut-être rétablir
IFS
la valeur avant, la stocker dans une variable temporaire.la source
/bin/sh
fonctionne pour moi sur OS X (liensbash
ici), mais je rencontre les mêmes problèmes sur Ubuntu Linux (liensh
versdash
). Essayez de changer le shebang (voir la réponse mise à jour),dash
ne semble pas interpréter le caractère\n
comme nouvelle ligne, mais le caractère 'n'. PS: +1 pour votre propre effort dans la résolution du problème et l'ajout d'un lien vers lazfs list
sortie de la question ne ferait de mal à personne, mais offrirait une référence. Soit dit en passant, vos onglets ont été remplacés par des espaces lors du téléchargement, il a fallu annuler cela avant decut
fonctionner correctement./bin/bash
n'a pas contourné. J'ai édité la question pour inclure plus de contexte et pour montrer plus clairement comment j'expérimente à partir de cette réponse. Succès partiel. Je pourrais faire une erreur très basique quelque part! Merci…printf
a été inutilement compliqué quand même, l' envelopper dans des guillemets doubles:zfs get all "$dataset"
. Je suppose que ça devrait bien se passer maintenant.