【问题标题】:Running a shell script through an automated Powershell folder listener通过自动 Powershell 文件夹侦听器运行 shell 脚本
【发布时间】:2023-03-27 16:48:01
【问题描述】:

在过去的几天里,我一直在整理一个 Powershell 脚本,以在 mcpcmag's articule 的帮助下监视我的 C 盘上的特定文件夹中的新文件。当最终用户请求电子邮件时,将创建新文件。新文件是一个 .sh 文件,其中包含一个 cURL 命令,该命令向SendGrid API 发送一个发布请求。

这是下面的 powershell 脚本:

# Create a listener for our emailOut directory 
$watcher = New-Object System.IO.FileSystemWatcher

# Set the path and turn on the listener 
$watcher.Path = 'C:\emailOut'
$watcher.EnableRaisingEvents = $true

$action =
{
    # set the shellScript to the full path of the added file
    $shellScript = $event.SourceEventArgs.fullPath
    # get the name of the file
    $name = (Get-Item $shellScript).Name
    # set the path which the file will be moved to on completion
    $oldFolderDir = "C:\emailOut\old\" + $name
    
    # run the script
    & $shellScript

    # set the log file path
    $logFile = "C:\emailOut\emailLog_" + $(get-date -format FileDate) + ".txt"

    # set the log message
    $logInfo = $name + " ---> " + $(get-date)

    # add entry to log file
    $logInfo | Out-File $logFile -Append -encoding utf8


    # Move the script file into the historic folder
    Move-Item -Path $shellScript -Destination $oldFolderDir

}

# Start the watcher
Register-ObjectEvent $watcher 'Created' -Action $action

cmets 使该过程相当不言自明,但为了简要描述,以下是发生(或应该发生)的情况:

  1. 文件进入被监视的文件夹
  2. Shell 脚本正在运行
  3. 条目已添加到日志文件中
  4. 文件已移至旧文件夹
  5. 完成

不幸的是,我运行 shell 脚本的方式似乎有问题。运行该过程时,很明显脚本正在运行,黑框出现了几分之一秒,但没有发送电子邮件。我检查了原始脚本,没有任何问题,因为当我双击 .sh 文件时,电子邮件已完美发送。

有什么想法吗?

提前感谢您的任何帮助或建议。

【问题讨论】:

    标签: powershell curl sendgrid


    【解决方案1】:

    我认为你这里有一个逻辑问题:

    文件进入被监视的文件夹
    [PowerShell]Shell 脚本运行

    问题是在您调用Register-ObjectEvent 之后,您的脚本结束,powershell 进程终止,这会隐式删除 FileSystemWatcher。 您应该在想要“捕获”事件的所有时间保持脚本运行。

    您可以通过计划任务运行它,选项Do not start a new instance 如果有实例正在运行并设置为每N分钟重复一次(如果出现故障或有人杀死进程,则恢复脚本,等)。此 PowerShell 实例必须正在运行才能继续获取事件。

    $eventSI = 'CustomSI_FSWCreated'
    
    $watcher = New-Object System.IO.FileSystemWatcher
    $watcher.Path = 'S:\SCRIPTS\FileTest'
    $watcher.EnableRaisingEvents = $true
    
    $action = { [System.Console]::WriteLine($event.SourceEventArgs.fullPath) }
    
    # Start the watcher
    Register-ObjectEvent -InputObject $watcher -EventName 'Created' -Action $action -SourceIdentifier $eventSI | Out-Null
    try
    {
        $l = 1;
        while($true)    
        {
            # Actually this timeout only sets the frequence of dots on your screen. Set it bigger if you want or remove Write-Host-s
            Wait-Event -Timeout 1 
            Write-Host "." -NoNewline
            $l++;
            if ($l -ge 40) 
            {
                Write-Host ""
                $l = 1;
            }
        }
    }
    finally
    {
        # This executes when you press Ctrl+C
        Unregister-Event -SourceIdentifier $eventSI
        $watcher.EnableRaisingEvents = $false
        $watcher.Dispose()
        Write-Host "Unregistered FSWE"
    }
    

    【讨论】:

    • 感谢@filmonic 的建议。您说得对,该任务需要保持运行,因此将您的示例付诸实践,以便我可以将其作为计划任务运行。但是,我认为这并不能回答原始问题,因为有问题的部分是我运行脚本的位置。 IE。 '& $shellScript'.
    • # 运行脚本 | & $shellScript 某人放入文件夹的文件,对吗?我建议在运行前延迟。可以创建文件,但尚未写入。
    【解决方案2】:

    只是想分享我的最终工作解决方案。 在运行脚本之前,我确实尝试过Start-Sleep -seconds 5,但不幸的是这并没有达到预期的结果。

    经过一番反复试验,我得出了一个可行的解决方案:

    # Create a listener for our emailOut directory 
    $watcher = New-Object System.IO.FileSystemWatcher
    
    # Set the path and turn on the listener 
    $watcher.Path = 'C:\emailOut'
    $watcher.EnableRaisingEvents = $true
    
    $action =
    {
       # set the shellScript to the full path of the added file
       $shellScript = $event.SourceEventArgs.fullPath
       # get the name of the file
       $name = (Get-Item $shellScript).Name
       #set the path which the file will be moved to on completion
       $oldFolderDir = "C:\emailOut\old\" + $name
    
       #### SOLUTION START ###
    
       #go to where bash.exe is stored
       cd "C:\Program Files\Git\bin"
    
       # run the script
       & .\bash.exe $shellScript
    
       ### SOLUTION END ###
    
       # set the log file path
       $logFile = "C:\emailOut\emailLog_" + $(get-date -format FileDate) + ".txt"
    
       # set the log message
       $logInfo = $name + " ---> " + $(get-date)
    
       # add entry to log file
       $logInfo | Out-File $logFile -Append -encoding utf8
    
    
       # Move the script file into the historic folder
       Move-Item -Path $shellScript -Destination $oldFolderDir
    
      }
    
      # Start the watcher
      Register-ObjectEvent $watcher 'Created' -Action $action
    

    基本上,我通过将 cURL 脚本传递给 git bash.exe 来运行我的脚本。 如有任何进一步的疑问或问题,请随时与我联系。

    帕特里克

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-27
      • 2016-03-08
      • 1970-01-01
      相关资源
      最近更新 更多