プログラムでファイルシステムのブロックデバイスを識別する[閉じる]

プログラムでファイルシステムのブロックデバイスを識別する[閉じる]

次のコードはRedHat 7で使用df verison 8.2およびテストされていますlsblk version 2.23.2。 lsblkユーティリティにはRedHat 6バージョン(2.17.2)よりも多くの出力オプションがあるため、これは重要です。

ファイルを含むファイルシステムを決定するのは非常に簡単です。

df -h /path/to/file | tail -n 1 | awk '{print $1}'

しかし、どのブロックデバイスにファイルシステムが含まれているかを確認することは非常に困難です。もちろん、ブロックデバイスを手動で決定する方法を使用することもできますが、lsblk -fそれを自動化された方法で実行する方法を知りたいです。

私はかなり深く掘り下げたが、これを行う方法を見つけることができませんでした。一般的なユースケースがあると思われるので奇妙です(ドライブのディレクトリをスキャンし、スキャンした物理ディスクのシリアル番号を取り戻します!)。

私は見苦しいテキスト解析を実行する再帰的なbash関数を作成しました。動作しますが、奇妙に見えます。 lsblkのドキュメントでは、その--outputスイッチを使用すると、バージョンアップ用の信頼性の高いスクリプトがあることを示唆しているようです。

function findBlockDevice {
  fileSystem="${1}"
  count="${2}"

  potentialBlockDeviceOutput=$(lsblk --paths --output name,type | grep "${fileSystem}" -B${count} | head -n 1)
  blockDevice=$(echo ${potentialBlockDeviceOutput} | awk '{print $1}')
  blockType=$(echo ${potentialBlockDeviceOutput} | awk '{print $2}')

  if [[ "${blockType}" != "disk" ]]; then
    count=$(( count + 1 ))
    findBlockDevice "${fileSystem}" "${count}"
  else
    echo "${blockDevice}"
  fi
}

使用法:

# Assume directory is on /dev/sda1
scanDirectory='/media/suspiciousDrive'
fileSystem=$(df -h ${scanDirectory} | tail -n 1 | awk '{print $1}')
blockDevice=$(findBlockDevice ${fileSystem} 0)

echo "${fileSystem}" # /dev/sda1
echo "${blockDevice}" # /dev/sda

# Now we can get the disk information to use in a report
lsblk --nodeps --paths --pairs --output NAME,SERIAL,MOUNTPOINT,VENDOR,\
    FSTYPE,UUID,MODEL,SIZE,TYPE,WWN,STATE ${fileSystem}

編集:ファイルシステムとディスクが提供されたときにlsblkユーティリティによって返される結果が異なるため、dfの出力は不十分です。次のコマンドは、ファイルシステムだけでなく、ブロックデバイス全体が与えられると、さまざまな情報を返します。

# Run this on your machine and notice the significant difference
lsblk --nodeps --paths --pairs --output NAME,SERIAL,VENDOR,MODEL /dev/sda
lsblk --nodeps --paths --pairs --output NAME,SERIAL,VENDOR,MODEL /dev/sda1

最終的に私は、「ドライブからどのディレクトリを検索しても、このハードドライブを検索し、自動的に物理デバイスのドライブ情報を返す」という問題に対する簡単な解決策が必要です。

解決策がありますが、かなり複雑で簡単な方法があるかどうか疑問に思います。

もう一つの編集:あまりにも多くの人がこれが重複していると思ったり、dfの出力が不十分な理由について混乱していることに驚きました。 df はブロックデバイスではなくファイルシステムを返します。ファイルシステムに情報を照会すると、シリアル番号やモデルなどのブロックデバイスのメタデータは返されません。ハードドライブのシリアル番号やハードドライブモデルをプログラムで知る必要があるのはなぜですか?これが誰の深刻なフォローアップの質問にならないことを願っています。

ベストアンサー1

提供されたコードを見ると、ファイルシステム上のファイルをそのファイルを含む物理ディスクに再マップできるようにしたいと思います。 RAID、LVM、または暗号化されたファイルシステムに関する考慮事項がないようです。

次のコードは、指定されたファイルを含むディスクデバイスを印刷します。 RAID および LVM の場合、ファイルは複数のデバイスに表示されることがあります。この場合、関連するすべてのディスクデバイス名が1行に1つずつ印刷されます。

read -p 'Filename: ' file
devpart=$(mount | awk -v mount=$(stat --format '%m' "$file") '$3 == mount {print $1}')
lsblk --list | awk -v part="${devpart/#*\/}" '$6 == "disk" {disk = $1} $6 != "disk" && $1 == part {print disk}'

おすすめ記事