I'd like to take output from two commands –
zpool list
zfs list
and for each found pool:
zpool get all nameofpool
and for each found file system:
zfs get all nameoffilesystem
Background and environment
I'm making local changes to script that's integral to OS X,
/usr/bin/sysdiagnose
#!/bin/sh
for starters- always run with superuser privileges
- sometimes effectively headless (triggered by a key chord), so the output must be a file.
First experiment
Based on the example at #65 Remove all ZFS snapshots:
#!/bin/sh
for dataset in `zfs list -H | cut -f 1`
do
zfs get all $dataset
done
That works, but not where there's a space in the name of the dataset. For example where the file system is zhandy/Pocket Time Machine
the output includes:
cannot open 'zhandy/Pocket': dataset does not exist
cannot open 'Time': dataset does not exist
cannot open 'Machine': dataset does not exist
Second experiment
… was based on the first answer to this question – using IFS
– and made the script more like Apple's. See revision 4.
Third experiment
Based on the accepted answer to this question – with IFS
, and quotation marks for "$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
Amongst the resulting files, ZFS file system properties.txt
lists properties for just one ZFS file system … a dataset with white space in its name.
The most desirable end result is properties:
- for all ZFS file systems
- in a file.
Removing the following string –
&> ${data_directory_path}/ZFS\ file\ system\ properties.txt
– does get properties for all ZFS file systems, in a window of Terminal but not in a file. That's enough for me to accept an answer.
The output to file criterion, which wasn't in my first edition of the question, may be easily answered elsewhere.
Best Answer
Not splitting at spaces
bash's
for
loop splits the argument at all whitespace characters by default. You could somehow escape each line - or simply switch to another delimiter character.cut
will return one value per line, so there's a newline in between which we can choose.Watch out for the double quotes in
zfs get all
, so each$dataset
doesn't get split up, too.Resetting IFS
Afterwards, you might want to reset
IFS
to the value before, store it to some temporary variable.