Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Отслеживать создания файла

Ответить
Настройки темы
CMD/BAT - [решено] Отслеживать создания файла

Новый участник


Сообщения: 11
Благодарности: 0

Профиль | Отправить PM | Цитировать


Доброго времени суток! Помогите сделать батник, нужно отслеживать создания файла Log.log с определенной периодичностью, когда файл создался отслеживать в нем появление слова successful также с периодичностью, при появлении successful выполнить код ниже.
Заранее всем откликнувшимся спасибо.

Отправлено: 12:28, 21-10-2018

 

Аватара для YuS_2

Crazy


Contributor


Сообщения: 1171
Благодарности: 487

Профиль | Отправить PM | Цитировать


не лучшая идея, использовать для этого cmd. Если на борту имеется powershell, то можно сделать без особых проблем...

-------
scio me nihil scire. Ѫ

Это сообщение посчитали полезным следующие участники:

Отправлено: 18:38, 21-10-2018 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Новый участник


Сообщения: 11
Благодарности: 0

Профиль | Отправить PM | Цитировать


Любой вариант подойдет.

Отправлено: 20:36, 21-10-2018 | #3


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1171
Благодарности: 487

Профиль | Отправить PM | Цитировать


Цитата alexfeel30:
нужно отслеживать создания файла Log.log с определенной периодичностью, когда файл создался отслеживать в нем появление слова successful»
Вот готовая функция слежения за каталогом, на создание файла:
Код: Выделить весь код
# Каталог, в котором будем следить за файлами
$pth = "c:\111\"
# Таймаут цикла ожидания (в мс.)
$tout = 1000
# Задержка чтения файла (в мс.)
$delay = 1000
# Объект следящий за появлением события:
$wtch = new-object system.io.filesystemwatcher
$wtch.path = $pth
# При необходимости задаём фильтр
$wtch.filter = "log.log"
do {
	$res = $wtch.waitforchanged("created", $tout)
    # Значение true, если время ожидания метода WaitForChanged истекло;
    # в противном случае — значение false.
	if ($res.timedout -eq $false){
		sleep -m $delay
		if ((gc ($pth+$res.name) -enc utf8 -raw) -match 'successful'){
			"выполняемый код"
		}
	}
} until ([system.console]::keyavailable)
Цитата alexfeel30:
также с периодичностью, при появлении successful выполнить код ниже. »
А вот тут уже не совсем понятно... что же требуется?
Отслеживать только появление файла с однократным его чтением, на предмет наличия слова или же ещё требуется отслеживание изменения файла? В принципе и это возможно, вопрос только в том, как часто он будет обновляться. В том смысле, что его обновления надо обрабатывать, а вот как это делать - вопрос. При каждом обновлении искать совпадение или же с каким-либо периодом времени?

-------
scio me nihil scire. Ѫ

Это сообщение посчитали полезным следующие участники:

Отправлено: 00:40, 22-10-2018 | #4


Ветеран


Сообщения: 27449
Благодарности: 8086

Профиль | Отправить PM | Цитировать


Цитата YuS_2:
А вот тут уже не совсем понятно... что же требуется? »
Коллега alexfeel30 сейчас выложит код на пакетных файлах, который нужно будет перевести на PowerShell.

Отправлено: 00:44, 22-10-2018 | #5


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1171
Благодарности: 487

Профиль | Отправить PM | Цитировать


Цитата Iska:
Коллега alexfeel30 сейчас выложит код на пакетных файлах »
ну, переводить необязательно... можно попытаться скрестить их

-------
scio me nihil scire. Ѫ


Отправлено: 01:08, 22-10-2018 | #6


Ветеран


Contributor


Сообщения: 2708
Благодарности: 1684

Профиль | Отправить PM | Цитировать


Цитата Iska:
Коллега alexfeel30 сейчас выложит код на пакетных файлах, который нужно будет перевести на PowerShell. »
А потом надо будет, чтобы окно выполнения не было видно.
Если интервал опроса кратен минуте, то лучше задание поставить в планировщик, пускай он задаёт интервал опроса, при этом код совсем простой (или я задачу не прочувствовал, в чём сложность CMD?)
Код: Выделить весь код
@Echo Off
	Set "File=Z:\Box_In\Log.Log"
	Set "Keyword=successful"

	If Not Exist "%File%" Exit /B 2
	Echo File Exist %File%

	Find /I "%Keyword%" "%File%" >nul || Exit /B 1
	Echo %Keyword% found
Exit /B 0
Если не жалко грузить компьютер более частым опросом и время задержки измерять секундами, то без планировщика
Код: Выделить весь код
@Echo Off

Set "File=Z:\Box_In\Log.Log"
Set "Keyword=successful"
Set "TOutSec=5"

Set "TOutCom=Timeout /T %TOutSec% >nul"

:Begin	
	If Not Exist "%File%" (%TOutCom% &GoTo :Begin)

	Find /I "%Keyword%" "%File%" >nul || (%TOutCom% &GoTo :Begin)

	Echo %Date% %Time% %Keyword% found

%TOutCom% &GoTo :Begin
Exit /B 0
А вот если надо чтобы окно не было видно - тогда вперёд на vbs/js

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.


Последний раз редактировалось megaloman, 22-10-2018 в 11:26.

Это сообщение посчитали полезным следующие участники:

Отправлено: 11:15, 22-10-2018 | #7


Ветеран


Сообщения: 3806
Благодарности: 824

Профиль | Отправить PM | Цитировать


YuS_2, зачем в PoSh все эти таймауты и задержки? - нужно просто подписаться на событие. И грузить в память весь файл тоже не надо. Это лог, который может достигать неслабых размеров.

Я бы примерно так сделал:

Код: Выделить весь код
$watchedFile = 'C:\temp\abc.log'
$waitingWord = 'successful'

$watcher = New-Object System.IO.FileSystemWatcher(Split-Path -LiteralPath $watchedFile)

$subscription = Register-ObjectEvent -InputObject $watcher -EventName Created -Action {
  if ($event.SourceEventArgs.Name -eq (Split-Path -Leaf $watchedFile)) {
    Get-Content -Path $watchedFile -Wait | % {if ($_ -match $waitingWord) {
        Write-Host "Обнаружено слово $waitingWord"
        Unregister-Event -SubscriptionId $subscription.Id
        break
      }
    }
  }
}
ему поплохеет, если вместо лога создать директорию с таким именем; ну и если лог уже есть, то отслеживать не будет
Это сообщение посчитали полезным следующие участники:

Отправлено: 12:42, 22-10-2018 | #8


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1171
Благодарности: 487

Профиль | Отправить PM | Цитировать


Цитата megaloman:
А потом надо будет, чтобы окно выполнения не было видно. »
дык, это вообще не проблема же.

Цитата Busla:
зачем в PoSh все эти таймауты и задержки? - нужно просто подписаться на событие. »
Да, возможно. Это была готовая функция у меня, чуть модифицировал только... для чего создавалась, уже и не упомню.

Цитата Busla:
И грузить в память весь файл тоже не надо. Это лог, который может достигать неслабых размеров. »
Согласен, можно и построчно парсить... а если файл достаточно большой, то можно и порциями строк... не принципиально.

А вообще, тут и велосипедов изобретать не надо, уже есть изобретенные до нас...
... вот тут есть чужой скриптик, опубликую со ссылкой на автора:
скрипт watchdog.ps1
Код: Выделить весь код
<# Garry Geller
Набор функций-командлетов для наблюдения за изменениями файлов\директорий на основе
класса FileSystemWatcher. Для удобства использования можно поместить их в файл 
powershell профиля - тогда они будут доступны наравне с прочими командами сразу из
консоли, либо поместить файл модуля watchdog.ps1 в папку powershell модулей.
#>
# required -version 3.0
set-alias swatch Set-Watch 
function Set-Watch() {
<#
    .SYNOPSIS
        Запускает фоновый процесс отслеживания изменений файловой системы на основе класса FileSystemWatcher
    .DESCRIPTION
        Существующие фильтры отслеживаемых изменений:
        NotifyFilters.CreationTime
        NotifyFilters.LastAccess
        NotifyFilters.LastWrite
        NotifyFilters.FileName
        NotifyFilters.DirectoryName
        NotifyFilters.Security
        NotifyFilters.Size
        NotifyFilters.Attributes
    .EXAMPLE
        PS C:\> . .\watchdog.ps1           
        PS C:\> swatch -path "d:\test" -filter "*.txt"  -event Created,Deleted 
    .EXAMPLE    
        PS C:\> swatch -path "d:\test" -filter "*.txt"  -event Created,Deleted  -command "start-process notepad.exe" -test
    .LINK 
        https://msdn.microsoft.com/ru-ru/lib...v=vs.110).aspx
    .LINK
        Remove-Watch
    .LINK
        Disable-Watch
    .LINK 
        Enable-Watch
    .LINK
        Get-Watch
#>
 
[CmdletBinding()] 
param(
    # путь до отслеживаемой директории
    [parameter(Mandatory=$true,Position=1)]
    [alias("p")][string]$path,                           
    [parameter(Mandatory=$true,Position=2)]
    # фильтр типов отслеживаемых файлов
    [alias("f")][string]$filter="*.*",                   
    # задает тип отслеживаемых изменений
    [alias("n")][string]$notify='FileName, LastWrite',   
    # нужно ли рекурсивно отслеживать субдиректории 
    [alias("r")][switch]$recurse,                        
     # событи(e|я) на котор(ое|ые) нужно реагировать
    [parameter(Mandatory=$true,Position=3)]
    [ValidateSet("Created","Deleted","Renamed","Changed")]
    [alias("e")][string[]]$events,                      
    [parameter(Mandatory=$false)]
    # строковые идентифкаторы событий
    [alias("name")][string[]]$id=@(),
    # действие которое нужно выполнить - передается одной строкой вместе с аругментами
    [string]$command,                                    
    # вывод переданных аргументов
    [switch]$test
    )
 
  
    $fsw = New-Object IO.FileSystemWatcher -Property @{
        Path = $path
        Filter = $filter
        IncludeSubdirectories = $recurse
        NotifyFilter = [IO.NotifyFilters]$notify
    }
    Set-Variable __watcher -Value $fsw -Scope Script
 
    Set-Variable command -Value $command -Scope Script
    
    $action = {
        #$command  = Get-Variable command -valueOnly -Scope Global
        $fullPath   = $event.SourceEventArgs.FullPath
        $fileName   = $event.SourceEventArgs.Name
        $changeType = $event.SourceEventArgs.ChangeType
        $timeStamp  = $event.TimeGenerated
        Write-Host "The file '$fileName' was $changeType at $timeStamp"
        
 
        if (![String]::IsNullOrEmpty($command)) {
            Invoke-Expression $command 
        }
 
    }
    
    $calls = [Collections.ArrayList]::new()
    
    for ($i=0; $i -lt $events.length; $i++) {
        
        if ($id.Length -eq $events.Length){
            $jobname = $id[$i]   
        } else {
            $jobname = $events[$i]
        }
        
        $params = @{SourceIdentifier = $jobname; Action = $action}
        if ((get-job).Name -ccontains $jobname) {
            Write-Host "Задание $jobname уже существует" -f Red
            
        } else {
            $regEvent = Register-ObjectEvent $fsw $events[$i] @params
            $calls.Add($regEvent)|Out-Null 
        }
        
    }
 
    # выводим аргументы функции
    if ($test) {
        $MyInvocation.BoundParameters.GetEnumerator() | Foreach { 
            echo "-$($_.Key): $($_.Value)"
        }
        $MyInvocation.UnboundArguments
        '----------------------------'
    }
 
    return $calls
}
 
set-alias unwatch Disable-Watch
function Disable-Watch() {
<#
    .SYNOPSIS
        Временно отключает обработку событий
    .LINK 
        Enable-Watch
    .LINK
        Remove-Watch
    .LINK
        Get-Watch
    .LINK
        Set-Watch
#>
    if ($__watcher) {
        $__watcher.EnableRaisingEvents = $false
        Write-Host "Отслеживание событий отключено" -f Yellow -b DarkGray
    }
}
 
set-alias watch Enable-Watch    
function Enable-Watch() {
<#
    .SYNOPSIS
        Включает обработку событий
    .LINK
        Disable-Watch
    .LINK
        Remove-Watch
    .LINK
        Get-Watch
    .LINK
        Set-Watch
#>    
    if ($__watcher) {
        $__watcher.EnableRaisingEvents = $true
        Write-Host "Отслеживание событий включено" -f Green -b DarkGray
    }
}
 
set-alias gwatch Get-Watch    
function Get-Watch() {
<#
    .SYNOPSIS
        Получает сторожевой объект для установки новых свойств (если указаны)
        и возвращает его 
    .EXAMPLE    
        PS C:\> (gwatch).filter = "*.*"     # установить новый файловый фильтр
        PS C:\> gwatch -Filter *.*
    .EXAMPLE    
        PS C:\> (gwatch).path= "c:\windows" # установить новую директорию для отслеживания
        PS C:\> gwatch -Path "c:\windows" 
    .EXAMPLE
        PS C:\> gwatch -NotifyFilter "Filename,LastWrite,LastAccess" -Filter "*.*"
    .EXAMPLE
        PS C:\> gwatch -IncludeSubdirectories
        PS C:\> gwatch -IncludeSubdirectories:$false
    .OUTPUTS
       FileSystemWatcher 
    .LINK
        Set-Watch
    .LINK
        Disable-Watch
    .LINK
        Remove-Watch
    .LINK
        Get-Watch 
#>    
param(
    [string]$Path,
    [string]$Filter,
    [switch][Boolean]$IncludeSubdirectories,
    [string]$NotifyFilter
 
)    
    if ($__watcher -eq $null) {
        Write-Host "Объект FileSystemWatcher не определен" -f Red
    } else { 
        
        $type_watcher = $__watcher.gettype()
        $MyInvocation.BoundParameters.GetEnumerator() | %{ 
           $key = $_.Key
           $value = $_.Value
           if ($key -eq "NotifyFilter") {
                $value = [IO.NotifyFilters]$value
           }
           if ($key -eq "IncludeSubdirectories") {
                [Boolean]$value = $value
           }
           $prop = $type_watcher.GetProperty($key)
           $prop.SetValue($__watcher, $value)
        }
        
        return $__watcher
    }
} 
 
 
set-alias rwatch Remove-Watch 
function Remove-Watch() {
<#
    .SYNOPSIS
        Удаляет задание по списку имен, либо все
    .EXAMPLE    
        PS C:\> rwatch Created,Deleted    # удалить задания по именам 
    .EXAMPLE    
        PS C:\> rwatch                    # удалить все задания
    .LINK 
        Set-Watch
#>     
    
    [CmdletBinding()]  
    param(
    [string[]]$names
    )
    if ($names.Length -eq 0) { 
        $names = (get-job).Name
    }
 
    
    
    foreach ($jobname in $names) {
        if ((get-job).Name -ccontains $jobname) {
            Unregister-Event $jobname -Force
            Remove-Job -Name $jobname -Force
            Write-Host "Задание $jobname удалено" -f Green -b DarkGray
        } else {
           Write-Host "Задание $jobname не найдено" -f Yellow -b DarkMagenta
        }
    }
    Set-Variable __watcher -Value $null -Scope Script
}

Полностью управляемый, подписывается на событие создания, изменения, удаления файлов, с возможностью ввода команд для исполнения. В общем, достаточно универсальный... удовлетворит любую потребность

-------
scio me nihil scire. Ѫ

Это сообщение посчитали полезным следующие участники:

Отправлено: 13:50, 22-10-2018 | #9


Новый участник


Сообщения: 11
Благодарности: 0

Профиль | Отправить PM | Цитировать


Всем спасибо, взял код megaloman-а все работает как надо.

Отправлено: 20:21, 22-10-2018 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Отслеживать создания файла

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
CMD/BAT - [решено] Дата создания (изменения) файла Arsenik77 Скриптовые языки администрирования Windows 8 05-10-2016 08:11
CMD/BAT - CMD проверка создания файла за (сегодня вчера) с созданием флагового файла yamixon Скриптовые языки администрирования Windows 5 17-03-2015 08:40
CMD/BAT - Проверка времени создания файла havenofear Скриптовые языки администрирования Windows 1 17-06-2012 01:06
CMD/BAT - [решено] Дата/время создания в имени файла art.andr Скриптовые языки администрирования Windows 8 09-04-2012 14:39
Время создания файла Alexey1974 Microsoft Windows NT/2000/2003 0 09-04-2007 20:28




 
Переход