5

Итак, я ищу подход командной строки для получения короткого (ish) текстового дампа относительно низкоуровневых метаданных для файла, примерно так же, как stat в системах * nix.

Другими словами, информация, которая легко доступна через файловые API-интерфейсы Win32 или NT без фактического чтения содержимого файла и, безусловно, без необходимости заходить где-либо рядом с оболочкой (как это видно в диалоговых окнах « Проводник» и «Сохранить / Открыть» и во все, что использует shell32.dll).

В NTFS эта информация, как правило , хранится в записи MFT файла, хотя я слышал, что от того, какие именно атрибуты заканчиваются в собственном MFT, во многом зависит, будет зависеть от того, какие из них являются необязательными, повторяемыми и / или переменный размер, некоторые могут быть, хотя также возможно использовать более одного слота в MFT. (Фактически, даже возможно сохранить полное содержимое файла / каталога в MFT, если другие атрибуты не занимают слишком много места!) Так что, очевидно, "появляется в MFT" нельзя использовать для определения того, что я ищу.

Кроме того, я не ищу инструменты, которые анализируют саму NTFS или работают только с файловыми системами NTFS: я упоминаю только NTFS, потому что, ну, а какая еще локальная ФС будет поддерживать более специфичные для NT вещи?

Для конкретности, вот stat на поле Debian, которое я использую в качестве маршрутизатора:

hydrogen% stat .
  File: ‘.’
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: fe00h/65024d    Inode: 507974      Links: 4
Access: (0755/drwxr-xr-x)  Uid: ( 1000/ naesten)   Gid: ( 1000/ naesten)
Access: 2016-08-31 14:12:47.650440935 -0400
Modify: 2016-09-20 17:26:15.935591584 -0400
Change: 2016-09-20 17:26:15.935591584 -0400
 Birth: -
hydrogen%

А вот что из Git для Windows:

цветная растровая версия ниже "скриншот"

Sam@Sam-laptop MINGW64 ~
$ git --version
git version 2.8.2.windows.1

Sam@Sam-laptop MINGW64 ~
$ stat .
  File: '.'
  Size: 0               Blocks: 32         IO Block: 65536  directory
Device: 147ac391h/343589777d    Inode: 1970324836977201  Links: 1
Access: (0755/drwxr-xr-x)  Uid: (197608/     Sam)   Gid: (197121/ UNKNOWN)
Access: 2016-09-18 18:32:28.072538600 -0400
Modify: 2016-09-18 18:32:28.072538600 -0400
Change: 2016-09-18 18:32:28.072538600 -0400
 Birth: 2014-08-21 18:52:08.217444400 -0400

Sam@Sam-laptop MINGW64 ~
$

В этот момент я собирался сказать, что поле отметки времени "рождения" - это Windowsism, но очевидно, что это не совсем так, потому что в статистике Debian это поле отображается, только оно пустое, потому что файловая система фактически не имеет этого поля. (Который, по крайней мере, гораздо понятнее , чем "Access" метка время:. Ни одна система не обновляет те , в традиционной манере strictatime

Также обратите внимание, как порт Windows отображает выданные разрешения на доступ к файлам, неправдоподобно большой "номер inode", и что я могу только предположить, это также составленные номера UID/GID (из-за того, как NT использует иерархические идентификаторы переменной длины) вместо номеров фиксированного размера для идентификации пользователей и групп, и не разрешает владение как пользователем, так и группой одновременно, то есть в NT файл принадлежит одной группе пользователя ИЛИ, а кто-то еще просто получает свои права из ACL).

Предоставляет ли MS инструмент такого рода, предположительно тот, который показывает более актуальную информацию и меньше информации о сказочных странах?


Мой оригинальный текст следует:

Да, я знаю, что есть порты stat , но (а) я обеспокоен тем, что информация может провалиться, если:

  1. Это обычно не появляется в выводе stat Unix
  2. Это отсутствует в каком-либо коде исходной stat (если есть)
  3. Портер (ы) либо
    1. Не замечайте, что Windows предоставляет информацию
    2. Создаем слой POSIX, который не проходит через него
    3. Не уверены, как лучше представить информацию (или что это даже уместно) в контексте stat
    4. Не имейте неограниченное количество времени на руках

и (б) мне было интересно, если Microsoft предоставила какой-либо аналогичный инструмент (ы).

Но на самом деле любой способ командной строки, позволяющий получить вид stat может представлять интерес (независимо от того, включает ли он программу, называемую stat), вместе с описанием более или менее специфичной для NTFS информации, которую он предоставляет.

PS Я нахожусь на Windows 7, но не позволяйте этому упоминать о вещах, впервые отправленных для / в более поздних версиях Windows.

4 ответа4

4

Я просто собрал сценарий PowerShell. Он включает в себя практически все, что имеет смысл для Windows, кроме элементов управления доступом, которые обычно слишком велики, чтобы уместиться в сводке. Вы можете увидеть их с помощью утилиты icacls .

$obj = $args[0]
If ($obj.GetType().Name -eq 'String') {$obj = gi $obj}
'File: ' + $obj.FullName
'Size: ' + $obj.Length
$extents = [string](fsutil file queryextents "$($obj.FullName)")
If (-$extents.StartsWith('i')) {
  'Clusters: ' + ($extents.Substring(26) -split 'LCN')[0]
  'LCN: ' + $extents.Substring(42)
} Else {
  'Clusters: stored in file table'
}
'Attributes: ' + $obj.Attributes
$volumeinfo = (fsutil fsinfo volumeinfo "$([System.IO.Path]::GetPathRoot($obj.FullName)[0] + ':')")
$volumeinfo | ? {$_.StartsWith('Volume Serial')} | % {$_.Replace(' :', ':')}
$fileid = (fsutil file queryfileid "$($obj.FullName)")
'File ID: ' + $fileid.Substring(11)
$links = (fsutil hardlink list "$($obj.FullName)")
'Links: ' + ([string[]]$links).Length
'Owner: ' + $obj.GetAccessControl().Owner
''
'Access: ' + $obj.LastAccessTime
'Modify: ' + $obj.LastWriteTime
'Create: ' + $obj.CreationTime
'' # Extra blank line for readability

Он использует обычные свойства записи файловой системы .NET/PowerShell и обращается к утилите fsutil за хитрыми штуками . Поскольку эта утилита не является командлетом PowerShell, мне пришлось сделать несколько грязных строк, чтобы получить нужную информацию.

Чтобы использовать его, сохраните его как файл .ps1 и посмотрите раздел «Включение сценариев» вики-тега PowerShell. Пример вывода:

File: C:\Users\Ben\test\blank.ps1
Size: 8
Clusters: stored in file table
Attributes: Archive
Volume Serial Number: 0x9c67b42c
File ID: 0x0000000000000000000700000014428b
Links: 1
Owner: POWERSHELL\Ben

Access: 07/29/2016 20:01:25
Modify: 07/29/2016 20:02:43
Create: 07/29/2016 20:01:25
2

Точного эквивалента нет, но самое близкое, что вы можете получить со встроенными утилитами Windows, - это команда fsutil. Он даст вам большинство вещей, которые предоставляет stat , а также более подробную информацию о базовой структуре файловой системы. Но в отличие от stat его нужно запускать с правами администратора. Вы также можете использовать wmic (или версию PowerShell Get-WmiObject (псевдоним gwmi )) для большого количества полезных данных. Для нескольких других вариантов вам нужно получить с другими командами

Ниже описано, как получить аналогичную информацию для параметров формата в stat (в PowerShell, с доступной версией cmd), которую можно использовать для настройки вывода. В противном случае просто fsutil file layout , fsutil fsinfo sectorinfo и fsutil fsinfo ntfsinfo

  • Права доступа: права доступа Windows сильно отличаются от прав доступа POSIX. Поэтому нет аналога % a. Однако существует подобная информация

  • Количество выделенных блоков (% b): Запустите fsutil file layout path\to\file или путь файла fsutil volume filelayout path\to\file и подсчитайте общее количество кластеров, выделенных в потоке $DATA .

    Например, для вывода ниже мы выделили 4 экстента, каждый из которых имеет длину 82, 432,419, 259 и 155,076 кластера соответственно. В результате количество выделенных блоков составляет 82 + 432419 + 259 + 155076 = 587836. Быстрый прием - добавить номер VCN последнего кластера с его длиной: 432760 + 155076 = 587836.

    Stream                  : 0x080  ::$DATA
        Attributes          : 0x00000000: *NONE*
        Flags               : 0x00000000: *NONE*
        Size                : 2.407.772.410
        Allocated Size      : 2.407.776.256
        Extents             : 4 Extents
                            : 1: VCN: 0 Clusters: 82 LCN: 1.620.482
                            : 2: VCN: 82 Clusters: 432.419 LCN: 5.331.392
                            : 3: VCN: 432.501 Clusters: 259 LCN: 3.230.067
                            : 4: VCN: 432.760 Clusters: 155.076 LCN: 9.299.239
    
  • Размер в байтах каждого блока, сообщаемого% b (% B):

    fsutil fsinfo ntfsinfo <drive> | findstr /c:"Bytes Per Cluster"`
    
  • Строка контекста безопасности SELinux (% C): нет сопоставимой функции

  • Номер устройства (% d, % D): нет аналога. Но вы можете использовать следующую команду, если вы хотите получить идентификатор устройства

    (Get-WmiObject win32_volume | where { $_.driveletter -eq '<drive>' }).deviceid
    
  • Необработанный режим в шестнадцатеричном формате (% f): нет эквивалентной формы Смотрите% a /% A выше

  • Тип файла (% F): Прямого эквивалента нет, так как модели файлов и драйверов Windows сильно различаются, и в Windows нет таких вещей, как символьные устройства, поэтому вы не получите "специальный символьный файл". Однако, как правило, вы можете использовать (ls path\to\file).Mode чтобы получить режим файла как% A выше, и (ls path\to\file).LinkType чтобы получить тип ссылки

  • Имя группы владельца (% G):

    (Get-Acl file.ext).Group
    
  • Идентификатор группы владельца (% g):

    (gwmi win32_useraccount | where { $_.caption -eq "$((Get-Acl file.ext).Group)" }).SID
    
  • Количество жестких ссылок (% h): подобной информации нет. Однако fsutil hardlink list path\to\file печатает все жесткие ссылки файла, поэтому мы можем легко сосчитать их с помощью

    (fsutil hardlink list path\to\file | Measure-Object).Count
    
    • В качестве альтернативы используйте (fsutil file layout path\to\file | sls -CaseSensitive -Pattern '^Link.+\s+:\s+0x[0-9a-f]+:\s*HLINK Name\s+:' | Measure-Object).Count
  • Номер инода (% i): в Windows нет инода, но NTFS (и, возможно, более новые файловые системы, такие как ReFS) имеют эквивалентный названный идентификатор файла, который можно извлечь из fsutil file layout или напрямую с помощью

    fsutil file queryfileid path\to\file
    
  • Имя файла (% n): это довольно очевидно

  • Имя файла в кавычках с разыменованием, если символическая ссылка (% N):

  • Размер блока ввода / вывода (% o): см. % S для файловых систем ниже

  • Общий размер в байтах (% s): (ls path\to\file).Length Или это можно легко увидеть в выводе dir cmd и в fsutil file layout path\to\file в поле Size как указано выше.

  • Тип устройства (% t, % T): см. % T для типа файловой системы ниже

  • Имя пользователя владельца (% U):

    (Get-Acl path\to\file).Owner
    
  • Идентификатор пользователя владельца (% u): SID пользователя можно получить с помощью следующей команды

    (gwmi win32_useraccount | where { $_.caption -eq "$((Get-Acl D:\zz.bat).owner)" }).SID
    
  • Время файла:

    • Время последнего доступа (% x): (ls path\to\file).LastAccessTime
    • Чтобы получить время последнего доступа с начала эпохи (% X): (ls path\to\file).LastAccessTime.Ticks или (ls path\to\file).LastAccessTime.ToFileTime() (в зависимости от того, какую эпоху вы хотите: 1/1/0001 или 1/1/1601), чтобы получить время файла в разрешении 100 нс
    • Точно так же время последней модификации (% y, % Y) может быть восстановлено с LastWriteTime
    • Получить время последнего изменения метаданных (% z, % Z) сложнее, и вам может потребоваться вызвать Win32 API из PowerShell.

Для файловых систем обычно вы можете использовать fsutil fsinfo ntfsinfo <drive> или fsutil fsinfo sectorinfo <drive> чтобы найти подробную информацию

  • Свободные блоки, доступные не суперпользователю (% a): Нет эквивалента. Но я думаю, что вы можете проверить это с fsutil quota query
  • Всего блоков данных в файловой системе (% b):

    fsutil fsinfo ntfsinfo <drive> | findstr /c:"Number Sectors"
    
  • Общее количество файловых узлов в файловой системе (% c): если речь идет о количестве инодов, то нет ограничений на число записей MFT в NTFS, а также во многих новых файловых системах Linux, таких как Btrfs или XFS. Размер файла MFT будет увеличен для хранения большего количества файловых записей. Общее количество записей MFT можно проверить с помощью fsutil fsinfo ntfsinfo <drive>

  • Свободные файловые узлы в файловой системе (% d): не уверен, что это такое. Если речь идет о количестве неиспользованных инодов, то, как сказано выше, обычно нет верхнего предела. Возможно, fsutil volume allocationreport <drive> будет работать

  • Свободные блоки в файловой системе (% f):

    • fsutil fsinfo ntfsinfo <drive> | findstr /c:"Free Clusters"
    • Более подробную информацию можно найти в fsutil volume allocationreport <drive>
  • Идентификатор файловой системы в шестнадцатеричном формате (% i): я не знаю, какой именно синоним в Windows, но они могут предоставить эту информацию

    fsutil fsinfo ntfsinfo <drive> | findstr /c:"Resource Manager Identifier" /c:"NTFS Volume Serial Number"
    (gwmi win32_volume | where { $_.driveletter -eq 'd:' }).serialnumber`
    
  • Максимальная длина имен файлов (% l):

    (gwmi win32_volume | where { $_.driveletter -eq <drive>  }).maximumfilenamelength
    
  • Размер блока (для более быстрых передач) (% s):

    fsutil fsinfo sectorinfo <drive> | findstr /c:"Performance"
    
  • Фундаментальный размер блока (для количества блоков) (% S):

    fsutil fsinfo sectorinfo <drive> | sls physical
    fsutil fsinfo ntfsinfo <drive> | sls physical
    (gwmi win32_volume | where { $_.driveletter -eq 'd:' }).blocksize
    
  • Тип: Для % T вы можете использовать fsutil fsinfo volumeinfo <drive> | findstr /c:"File System Name" . Я не уверен, что такое % t , но похоже, что это магическое число раздела

(Get-WmiObject win32_ALIAS | where { $_.FILTERFIELD -eq 'VALUE' }).GETFIELD могут быть изменены на wmic ALIAS where FILTERFIELD='VALUE' get GETFIELD /value . Однако wmic устарела, поэтому в будущем его можно будет удалить.

2

Get-Item /path/to/file | Format-List должен получить то, что вам нужно, используя только собственные командлеты.

Get-Item получает информацию о любом интересующем вас файле. Format-List , несколько неинтуитивно, предоставит больше параметров хосту PowerShell, чем было бы иначе. Он также форматирует его в виде списка, как и следовало ожидать.

 ~> Get-Item ./temp.txt | Format-List


    Directory: /Users/brianshacklett


Name           : temp.txt
Length         : 989
CreationTime   : 4/5/18 9:52:04 PM
LastWriteTime  : 4/5/18 9:52:04 PM
LastAccessTime : 6/26/18 7:58:18 PM
Mode           : ------
LinkType       :
Target         :
VersionInfo    : File:             /Users/brianshacklett/temp.txt
                 InternalName:
                 OriginalFilename:
                 FileVersion:
                 FileDescription:
                 Product:
                 ProductVersion:
                 Debug:            False
                 Patched:          False
                 PreRelease:       False
                 PrivateBuild:     False
                 SpecialBuild:     False
                 Language:

Если вас беспокоит многословие, вы можете использовать псевдонимы, чтобы сократить это до gi /path to file | fl

0

Инструмент, который вы используете, использует среду, которая действует как тонкий слой между Windows и Linux и поэтому должна эмулировать определенные части, чтобы инструменты Linux могли делать свое дело. Это объясняет, почему существует некоторая сфабрикованная информация, которая (надеюсь) сопоставляется в согласованном вопросе. Вы должны взглянуть на специфику среды, реализующей ее, чтобы понять это.

С другой стороны, (для меня) не совсем понятно, что вы ищете. Как вы сказали, есть различные API, которые вы не хотите использовать. Является ли эта "эмулированная" информация актуальной для вас?

В противном случае вам, вероятно, понадобится множество инструментов для получения всей необходимой вам информации. Насколько мне известно, права доступа и ACL достаточно глубоко укоренены в NTFS. Такие инструменты, как icalcs могут помочь вам получить информацию о правах доступа из командной строки. Чтобы получить более подробную информацию (для некоторых ее частей), вы можете рассмотреть возможность использования WMI, как показано в этом примере. Простой dir или get-childitem из PowerShell может дать вам больше информации о времени создания и тому подобное. Я не знаю ни о каких встроенных инструментах, которые бы давали вам исчерпывать всю эту информацию. Что вы можете сделать, это использовать информацию об API и обернуть их в сценарий PowerShell. Это может приблизиться к тому, что вы действительно хотите сделать. Я не уверен, что есть сценарий, который уже делает это.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .