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

3734
SamB

Итак, я ищу подход командной строки для получения короткого (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:

colored raster version of below "screenshot"

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 отображает выданные разрешения на доступ к файлам, неправдоподобно большой «номер 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.

3
Возможные дубли: [Информация о файле или каталоге] (https://superuser.com/q/242307) DavidPostill 8 лет назад 1
Загляните на http://ss64.com/vb/filesystemobject.html, когда у вас появится такая возможность ... вы также можете найти ее полезной. Pimp Juice IT 8 лет назад 0
Уважаемый близкий избиратель! Если вы считаете, что * мой * вопрос слишком широкий, взгляните на один связанный с DavidPostill: он состоит из четырех * открытых * частей, и две из них ищут ответы как для Linux *, так и для Windows 7. SamB 8 лет назад 0
[WSL] (https://blogs.msdn.microsoft.com/wsl/2016/06/15/wsl-file-system-support/) и Cygwin используют [NTFS fileID] (https://stackoverflow.com/ q / 44162664/995714) как номер инода, который легко проверить. Если мы преобразуем 1970324836977201 в шестнадцатеричный код, мы получим 0x7000000000A31, который имеет всего несколько установленных бит. OTOH [* В файловых системах, которые не поддерживают уникальные постоянные идентификаторы файлов (FAT, более старые общие ресурсы Samba), номер инода для файла вычисляется путем хеширования его полного пути Win32. *] (Http://cygwin.com/cygwin- UG-сеть / Cygwin-UG-net.pdf) phuclv 6 лет назад 0

4 ответа на вопрос

4
Ben N

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

Там нет точных равнозначно, но ближе вы можете получить с 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устарел, поэтому в будущем он может быть удален

1
bshacklett

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

Интересно отметить, что на вашем компьютере `CreationTime == LastWriteTime`, а на моем компьютере:` CreationTime == LastAccessTime`. Что заставляет меня сомневаться, что * AccessTime * имеет какое-либо действие вообще. not2qubit 5 лет назад 0
0
Seth

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

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

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

Да, у меня есть приблизительное представление о том, как работают статистические порты Windows, этот, как оказалось, использует MSYS2. Что касается того, что я хотел, мне было любопытно, был ли у MS уже какой-то примерно аналогичный инструмент, уже встроенный, возможно, в один из их многочисленных «наборов», или что это был какой-то известный сторонний бесплатный инструмент. И дело не в том, что я * отказываюсь * использовать API или что-то еще, просто в этом больше работы. (В любом случае, если бы это было моей целью, я бы спросил об API на SO.) SamB 8 лет назад 0
Или, по крайней мере, SO был бы тем местом, где я хотел бы спросить об API: я подозреваю, что вопрос, который вы связали, [Что такое альтернатива lstat () в Windows?] (Http://stackoverflow.com/questions/ 12085761 / what-is-lstat-alternative-in-windows) привлек бы мое внимание, когда я работал над своим названием, если бы не раньше. (Да, функция «показать заголовок связанного вопроса» не только не работает в комментариях, но, по-видимому, также не работает и нотация «<>»?) SamB 8 лет назад 0
... хотя не все так хорошо ответили ... SamB 8 лет назад 0