Windows эквивалентна команде unix "stat"?

Итак, я ищу подход командной строки для получения короткого (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 это поле отображается, только оно пустое, потому что файловая система фактически не имеет этого поля. (Что, по крайней мере, намного яснее, чем временные метки "Доступ": ни одна из систем не обновляет таковые в традиционных strictatime способ.)

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

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


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

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

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

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

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

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

4 ответа

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

Ниже описано, как получить аналогичную информацию для параметров формата в 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
    
  • The size in bytes of each block reported by %b (%B):

    fsutil fsinfo ntfsinfo <drive> | findstr /c:"Bytes Per Cluster"`
    
  • SELinux security context string (%C): No comparable feature

  • Device number (%d, %D): No similar counterpart. But you can use the following command if you want to get the device ID

    (Get-WmiObject win32_volume | where { $_.driveletter -eq '<drive>' }).deviceid
    
  • Raw mode in hex (%f): No equivalent form. See %a/%A above

  • File type (%F): No direct equivalent, since Windows file and driver models are very different and there are no such things like character devices on Windows so you won't get "character special file". However generally you can use (ls path\to\file).Mode to get the file mode like %A above, and (ls path\to\file).LinkType to get link type

  • Group name of owner (%G):

    (Get-Acl file.ext).Group
    
  • Group ID of owner (%g):

    (gwmi win32_useraccount | where { $_.caption -eq "$((Get-Acl file.ext).Group)" }).SID
    
  • Number of hard links (%h): There are no similar information. тем не мение fsutil hardlink list path\to\file prints all the hard links of a file, so we can easily count them with

    (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
  • Inode number (%i): There's no inode in Windows, but NTFS (and possibly newer file systems like ReFS) has an equivalent called file ID that can be extracted from fsutil file layout output or directly with

    fsutil file queryfileid path\to\file
    
  • File name (%n): This is quite obvious

  • Quoted file name with dereference if symbolic link (%N):

    • (ls path\to\file | ?{$_.LinkType} | select FullName,LinkType,Target
    • или же dir path\to\file in cmd, with the symbolic name in square brackets
  • I/O block size (%o): see %s for file systems below

  • Total size, in bytes (%s): (ls path\to\file).Length, Or can be easily seen in cmd's dir output, and in fsutil file layout path\to\file output under the Size field like above

  • Device type (%t, %T): See %T for file system type below

  • User name of owner (%U):

    (Get-Acl path\to\file).Owner
    
  • User ID of owner (%u): You can get the user SID with the below command

    (gwmi win32_useraccount | where { $_.caption -eq "$((Get-Acl D:\zz.bat).owner)" }).SID
    
  • File time:

    • Last access time (%x): (ls path\to\file).LastAccessTime
    • To get the last access time since Epoch (%X): (ls path\to\file).LastAccessTime.Ticks или же (ls path\to\file).LastAccessTime.ToFileTime() (depending on which Epoch you want: 1/1/0001 or 1/1/1601) to get the file time in 100ns resolution
    • Similarly last modification time (%y, %Y) can be retrived with LastWriteTime
    • Getting last metadata change time (%z, %Z) is trickier and you may need to call win32 APIs from PowerShell

For file systems generally you can use fsutil fsinfo ntfsinfo <drive> или же fsutil fsinfo sectorinfo <drive> to find detailed information

  • Free blocks available to non-superuser (%a): No equivalent. But I think you can check it with fsutil quota query
  • Total data blocks in file system (%b):

    fsutil fsinfo ntfsinfo <drive> | findstr /c:"Number Sectors"
    
  • Total file nodes in file system (%c): If it's about the number of inodes then there's no MFT record limit on NTFS as well as many newer Linux filesystems like Btrfs or XFS. The MFT file size will be increased to store more file records. The total number of MFT records can be checked with fsutil fsinfo ntfsinfo <drive>

  • Free file nodes in file system (%d): Not sure what this is. If it's about the number of unused inodes then as said above, there's generally no upper limit. возможно fsutil volume allocationreport <drive> буду работать

  • Free blocks in file system (%f):

    • fsutil fsinfo ntfsinfo <drive> | findstr /c:"Free Clusters"
    • More detailed information can be found with fsutil volume allocationreport <drive>
  • File System ID in hex (%i): I don't know what's the exact synonymous on Windows but these may provide that information

    fsutil fsinfo ntfsinfo <drive> | findstr /c:"Resource Manager Identifier" /c:"NTFS Volume Serial Number"
    (gwmi win32_volume | where { $_.driveletter -eq 'd:' }).serialnumber`
    
  • Maximum length of filenames (%l):

    (gwmi win32_volume | where { $_.driveletter -eq <drive>  }).maximumfilenamelength
    
  • Block size (for faster transfers) (%s):

    fsutil fsinfo sectorinfo <drive> | findstr /c:"Performance"
    
  • Fundamental block size (for block counts) (%S):

    fsutil fsinfo sectorinfo <drive> | sls physical
    fsutil fsinfo ntfsinfo <drive> | sls physical
    (gwmi win32_volume | where { $_.driveletter -eq 'd:' }).blocksize
    
  • Type: For %T you can use fsutil fsinfo volumeinfo <drive> | findstr /c:"File System Name", I'm not sure what %t is but it seems that's the magic number of the partition

(Get-WmiObject win32_ALIAS | where { $_.FILTERFIELD -eq 'VALUE' }).GETFIELD commands above can be changed to wmic ALIAS where FILTERFIELD='VALUE' get GETFIELD /value, тем не мение wmic was deprecated so in the future it may be removed

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

Я просто собрал сценарий 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

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

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

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

Другие вопросы по тегам