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
, но (а) я обеспокоен тем, что информация может провалиться, если:
- Это обычно не появляется в Unix
stat
выход - Это отсутствует от того, что
stat
код апстрима (если есть) - Портер (ы) либо
- Не замечайте, что Windows предоставляет информацию
- Создаем слой POSIX, который не проходит через него
- Не уверены, как лучше представить информацию (или что это даже уместно сделать) в контексте
stat
- Не имейте неограниченное количество времени на руках
и (б) мне было интересно, если 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. Однако существует подобная информация
- Если вы хотите получить права доступа к файлам, используйте
Get-Acl
или жеicacls
, Подробнее в Windows: список файлов и их разрешения (доступ) в командной строке Если вы просто хотите режим файла, то одного из них будет достаточно, и он ближе всего к % A
(ls path\to\file).Mode for %i in (path\to\file) do echo %~ai in cmd
- Если вы хотите получить права доступа к файлам, используйте
Количество выделенных блоков (% 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 typeGroup 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 withfsutil 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'sdir
output, and infsutil file layout path\to\file
output under theSize
field like aboveDevice 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
- Last access time (%x):
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. Это может приблизиться к тому, что вы действительно хотите сделать. Я не уверен, что есть сценарий, который уже делает это.