node --- > 监听文件变化(静态、动态、子进程)

这篇博客介绍了如何在Node.js中监听文件变化,包括静态版本(监听固定文件名)和动态版本(根据命令行输入监听文件)。当文件发生变化时,采用子进程执行系统命令,利用child-process模块实现进程间的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

静态版本:监听的文件名写死了

// watcher.js
'use strict'
const fs = require('fs');
fs.watch('target.txt', () => console.log('File changed!'));
console.log('Now watching target.txt for changes...');
  • 命令行启动
node watcher.js

动态版本:在命令行输入需要监听的文件名.

  • process 全局对象,获取命令行输入的文件名
// watcher-argv.js
'use strict'
const fs = require('fs');
console.log(process.argv);
const filename = process.argv[2];
if (!filename) {
    throw Error('A file to watch must be specified!');
}
fs.watch(filename, () => { console.log(`File ${filename} changed!`));
console.log(`Now watching ${filename} for changes...`);

在这里插入图片描述

使用子进程对变化文件进行操作

  • 在开发中最常见的做法是把不同的工作放在不同的独立进程中执行
  • 在监听到文件变化后,创建一个子进程,再用这个子进程执行系统命令
  • child-process模块是node.js中的子进程模块
// watcher-spawn.js
'use strict';
const fs = require('fs');
const spawn = require('child_process').spawn;
const filename = process.argv[2];

if (!filename) {
    throw Error('A file to watch must be specified!');
}

fs.watch(filename, () => {
    const ls = spawn('ls', ['-l', '-h', filename]);
    ls.stdout.pipe(process.stdout);
});
console.log(`Now watching ${filename} for changes...`);
PS C:\Users\Administrator> # 修改后的启动命令 >> try { >> Start-Process -FilePath "pwsh" ` >> -ArgumentList "-Command `"$StartCommand 2>&1`"" ` >> -RedirectStandardOutput $logFile ` >> -WindowStyle Hidden >> } >> 所在位置 行:7 字符: 2 + } + ~ Try 语句缺少自己的 Catch 或 Finally 块。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : MissingCatchOrFinally PS C:\Users\Administrator> fatal: destination path '...' already exists and is not an empty directory >> fatal: : 无法将“fatal:”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径 正确,然后再试一次。 所在位置 行:1 字符: 1 + fatal: destination path '...' already exists and is not an empty dire ... + ~~~~~~ + CategoryInfo : ObjectNotFound: (fatal::String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException PS C:\Users\Administrator> function Update-Project { >> param(...) >> >> if (-not (Test-Path $gitDir)) { >> if (Get-ChildItem -Path $projectDir -ErrorAction SilentlyContinue) { >> # 备份现有目录 >> $backupDir = "$projectDir.backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')" >> Move-Item -Path $projectDir -Destination $backupDir >> Write-Host "⚠️ 已备份现有目录到: $backupDir" -ForegroundColor Yellow >> } >> git clone $RepoUrl $projectDir >> } >> else { >> Set-Location $projectDir >> git pull origin main >> } >> } >> 所在位置 行:2 字符: 11 + param(...) + ~ 函数参数列表中缺少“)”。 所在位置 行:1 字符: 25 + function Update-Project { + ~ 语句块或类型定义中缺少右“}”。 所在位置 行:2 字符: 14 + param(...) + ~ 表达式或语句中包含意外的标记“)”。 所在位置 行:17 字符: 1 + } + ~ 表达式或语句中包含意外的标记“}”。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : MissingEndParenthesisInFunctionParameterList PS C:\Users\Administrator> # 修改配置加载方式 >> $config = Import-Clixml -Path $ecosystemConfig >> >> # 修改属性访问方式 >> $projectType = ($config.Projects | Where-Object { $_.Name -eq $ProjectName }).Type >> switch ($projectType) { >> ... >> } >> 所在位置 行:7 字符: 8 + ... + ~ switch 语句的子句中缺少语句块。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : MissingSwitchStatementClause PS C:\Users\Administrator> # 修改配置加载方式 >> $config = Import-Clixml -Path $ecosystemConfig >> >> # 修改属性访问方式 >> $projectType = ($config.Projects | Where-Object { $_.Name -eq $ProjectName }).Type >> switch ($projectType) { >> ... >> } >> 所在位置 行:7 字符: 8 + ... + ~ switch 语句的子句中缺少语句块。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : MissingSwitchStatementClause PS C:\Users\Administrator> # 使用完整路径执行安装脚本 >> & "E:\Install-EcosystemService.ps1" -Action Install >> 位于命令管道位置 1 的 cmdlet New-Service 请为以下参数提供值: BinaryPathName: # 使用完整路径执行安装脚本 Status Name DisplayName ------ ---- ----------- Stopped ProjectEcosyste... ProjectEcosystemManager -BinaryPathName : 无法将“-BinaryPathName”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包 括路径,请确保路径正确,然后再试一次。 所在位置 E:\Install-EcosystemService.ps1:13 字符: 13 + -BinaryPathName "powershell.exe -File "$scriptPath" -Wind ... + ~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (-BinaryPathName:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException -DisplayName : 无法将“-DisplayName”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径 ,请确保路径正确,然后再试一次。 所在位置 E:\Install-EcosystemService.ps1:14 字符: 13 + -DisplayName "Project Ecosystem Manager" + ~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (-DisplayName:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException -Description : 无法将“-Description”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径 ,请确保路径正确,然后再试一次。 所在位置 E:\Install-EcosystemService.ps1:15 字符: 13 + -Description "Manages and monitors the entire project eco ... + ~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (-Description:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException -StartupType : 无法将“-StartupType”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径 ,请确保路径正确,然后再试一次。 所在位置 E:\Install-EcosystemService.ps1:16 字符: 13 + -StartupType Automatic + ~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (-StartupType:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException Start-Service : 由于以下错误无法启动服务“ProjectEcosystemManager (ProjectEcosystemManager)”: 无法启动计算机“.”上的 服务 ProjectEcosystemManager。 所在位置 E:\Install-EcosystemService.ps1:17 字符: 9 + Start-Service $serviceName + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OpenError: (System.ServiceProcess.ServiceController:ServiceController) [Start-Service], ServiceCommandException + FullyQualifiedErrorId : CouldNotStartService,Microsoft.PowerShell.Commands.StartServiceCommand PS C:\Users\Administrator> & "E:\Install-EcosystemService.ps1" -Action Install 位于命令管道位置 1 的 cmdlet New-Service 请为以下参数提供值: BinaryPathName: param( New-Service : 由于以下错误无法创建服务“ (ProjectEcosystemManager)”: 指定的服务已存在。 所在位置 E:\Install-EcosystemService.ps1:12 字符: 9 + New-Service -Name $serviceName + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : PermissionDenied: (ProjectEcosystemManager:String) [New-Service], ServiceCommandExceptio n + FullyQualifiedErrorId : CouldNotNewService,Microsoft.PowerShell.Commands.NewServiceCommand -BinaryPathName : 无法将“-BinaryPathName”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包 括路径,请确保路径正确,然后再试一次。 所在位置 E:\Install-EcosystemService.ps1:13 字符: 13 + -BinaryPathName "powershell.exe -File "$scriptPath" -Wind ... + ~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (-BinaryPathName:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException -DisplayName : 无法将“-DisplayName”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径 ,请确保路径正确,然后再试一次。 所在位置 E:\Install-EcosystemService.ps1:14 字符: 13 + -DisplayName "Project Ecosystem Manager" + ~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (-DisplayName:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException -Description : 无法将“-Description”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径 ,请确保路径正确,然后再试一次。 所在位置 E:\Install-EcosystemService.ps1:15 字符: 13 + -Description "Manages and monitors the entire project eco ... + ~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (-Description:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException -StartupType : 无法将“-StartupType”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径 ,请确保路径正确,然后再试一次。 所在位置 E:\Install-EcosystemService.ps1:16 字符: 13 + -StartupType Automatic + ~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (-StartupType:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException Start-Service : 由于以下错误无法启动服务“ProjectEcosystemManager (ProjectEcosystemManager)”: 无法启动计算机“.”上的 服务 ProjectEcosystemManager。 所在位置 E:\Install-EcosystemService.ps1:17 字符: 9 + Start-Service $serviceName + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OpenError: (System.ServiceProcess.ServiceController:ServiceController) [Start-Service], ServiceCommandException + FullyQualifiedErrorId : CouldNotStartService,Microsoft.PowerShell.Commands.StartServiceCommand PS C:\Users\Administrator> [Parameter(Mandatory=$true)] >> [ValidateSet("Install", "Uninstall", "Start", "Stop")] >> [string]$Action PS C:\Users\Administrator> ) 所在位置 行:1 字符: 1 + ) + ~ 表达式或语句中包含意外的标记“)”。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : UnexpectedToken PS C:\Users\Administrator> PS C:\Users\Administrator> $serviceName = "ProjectEcosystemManager" PS C:\Users\Administrator> $scriptPath = "E:\ProjectEcosystem\ProjectMonitor\Scripts\ProjectEcosystemManager.ps1" PS C:\Users\Administrator> PS C:\Users\Administrator> # 验证脚本是否存在 PS C:\Users\Administrator> if (-not (Test-Path $scriptPath)) { >> Write-Host "❌ 主脚本不存在: $scriptPath" -ForegroundColor Red >> exit 1 >> } PS C:\Users\Administrator> PS C:\Users\Administrator> switch ($Action) { >> "Install" { >> # 检查服务是否已存在 >> if (Get-Service -Name $serviceName -ErrorAction SilentlyContinue) { >> Write-Host "ℹ️ 服务已存在,先卸载..." -ForegroundColor Yellow >> & $MyInvocation.MyCommand.Path -Action Uninstall >> } >> >> New-Service -Name $serviceName ` >> -BinaryPathName "powershell.exe -ExecutionPolicy Bypass -File `"$scriptPath`" -WindowStyle Hidden" ` >> -DisplayName "Project Ecosystem Manager" ` >> -Description "自动化管理项目生态系统" ` >> -StartupType Automatic >> >> Start-Service $serviceName >> Write-Host "✅ 服务安装成功" -ForegroundColor Green >> } >> "Uninstall" { >> if (Get-Service -Name $serviceName -ErrorAction SilentlyContinue) { >> Stop-Service $serviceName -Force -ErrorAction SilentlyContinue >> sc.exe delete $serviceName | Out-Null >> Write-Host "✅ 服务卸载成功" -ForegroundColor Green >> } >> else { >> Write-Host "ℹ️ 服务不存在,无需卸载" -ForegroundColor Cyan >> } >> } >> "Start" { >> Start-Service $serviceName >> Write-Host "✅ 服务已启动" -ForegroundColor Green >> } >> "Stop" { >> Stop-Service $serviceName >> Write-Host "✅ 服务已停止" -ForegroundColor Yellow >> } >> } PS C:\Users\Administrator> PS C:\Users\Administrator> <!DOCTYPE html> >> <html lang="zh-CN"> >> <head> >> <meta charset="UTF-8"> >> <title>项目生态系统仪表板</title> >> <style> >> :root { >> --primary-color: #2c3e50; >> --secondary-color: #3498db; >> --success-color: #2ecc71; >> --warning-color: #f39c12; >> --danger-color: #e74c3c; >> } >> body { >> font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; >> margin: 0; >> padding: 20px; >> background: #f5f7fa; >> } >> .dashboard { >> display: grid; >> grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); >> gap: 20px; >> } >> .card { >> background: white; >> border-radius: 10px; >> box-shadow: 0 4px 12px rgba(0,0,0,0.1); >> overflow: hidden; >> transition: transform 0.3s ease; >> } >> .card:hover { >> transform: translateY(-5px); >> } >> .card-header { >> background: var(--primary-color); >> color: white; >> padding: 15px; >> font-weight: bold; >> } >> .card-body { >> padding: 20px; >> } >> .status { >> display: flex; >> align-items: center; >> margin-bottom: 15px; >> } >> .status-indicator { >> width: 12px; >> height: 12px; >> border-radius: 50%; >> margin-right: 10px; >> } >> .status-running { >> background: var(--success-color); >> } >> .status-stopped { >> background: var(--danger-color); >> } >> .btn { >> background: var(--secondary-color); >> color: white; >> border: none; >> padding: 8px 15px; >> border-radius: 4px; >> cursor: pointer; >> margin-right: 10px; >> transition: background 0.3s; >> } >> .btn:hover { >> opacity: 0.9; >> } >> .metrics { >> display: grid; >> grid-template-columns: 1fr 1fr; >> gap: 10px; >> margin-bottom: 15px; >> } >> .metric { >> background: #f8f9fa; >> padding: 10px; >> border-radius: 5px; >> font-size: 0.9em; >> } >> .metric-title { >> font-weight: bold; >> color: #7f8c8d; >> margin-bottom: 3px; >> } >> </style> >> </head> >> <body> >> <h1>项目生态系统监控仪表板</h1> >> >> <div class="dashboard" id="dashboard"> >> <!-- 动态生成项目卡片 --> >> </div> >> >> <script> >> // API端点 >> const API_URL = "http://localhost:5000/api/status"; >> >> // 初始项目数据 >> let projects = []; >> >> // 从API获取状态 >> async function fetchProjectStatus() { >> try { >> const response = await fetch(API_URL); >> if (!response.ok) throw new Error('Network error'); >> projects = await response.json(); >> renderDashboard(); >> } catch (error) { >> console.error('获取状态失败:', error); >> // 回退到静态数据 >> projects = [ >> { id: 1, name: "APIServer", type: "NodeJS", status: "running", cpu: "15%", memory: "120MB", uptime: "12小时" }, >> { id: 2, name: "BackendService", type: ".NET", status: "running", cpu: "22%", memory: "210MB", uptime: "8小时" }, >> { id: 3, name: "DataAnalysis", type: "Python", status: "stopped", cpu: "0%", memory: "0MB", uptime: "N/A" }, >> { id: 4, name: "EcoMonitor", type: "PowerShell", status: "running", cpu: "5%", memory: "80MB", uptime: "24小时" } >> ]; >> renderDashboard(); >> } >> } >> >> // 渲染仪表板 >> function renderDashboard() { >> const dashboard = document.getElementById('dashboard'); >> dashboard.innerHTML = ''; >> >> projects.forEach(project => { >> const card = document.createElement('div'); >> card.className = 'card'; >> card.id = `project-${project.id}`; >> >> const statusClass = project.status === 'running' ? >> 'status-running' : 'status-stopped'; >> const statusText = project.status === 'running' ? '运行中' : '已停止'; >> >> card.innerHTML = ` >> <div class="card-header">${project.name}</div> >> <div class="card-body"> >> <div class="status"> >> <div class="status-indicator ${statusClass}"></div> >> <span><strong>状态:</strong> ${statusText}</span> >> </div> >> <div class="metrics"> >> <div class="metric"> >> <div class="metric-title">类型</div> >> ${project.type} >> </div> >> <div class="metric"> >> <div class="metric-title">CPU</div> >> ${project.cpu} >> </div> >> <div class="metric"> >> <div class="metric-title">内存</div> >> ${project.memory} >> </div> >> <div class="metric"> >> <div class="metric-title">运行时间</div> >> ${project.uptime} >> </div> >> </div> >> <div class="actions"> >> <button class="btn restart-btn" data-id="${project.id}">重启</button> >> <button class="btn logs-btn" data-id="${project.id}" style="background: #7f8c8d;">查看日 志</button> >> </div> >> </div> >> `; >> >> dashboard.appendChild(card); >> }); >> >> // 添加事件监听器 >> document.querySelectorAll('.restart-btn').forEach(btn => { >> btn.addEventListener('click', () => restartProject(btn.dataset.id)); >> }); >> >> document.querySelectorAll('.logs-btn').forEach(btn => { >> btn.addEventListener('click', () => viewLogs(btn.dataset.id)); >> }); >> } >> >> // 项目操作函数 >> async function restartProject(id) { >> const project = projects.find(p => p.id == id); >> try { >> const response = await fetch(`${API_URL}/restart/${id}`, { method: 'POST' }); >> if (response.ok) { >> alert(`✅ ${project.name} 重启指令已发送`); >> } else { >> throw new Error('重启失败'); >> } >> } catch (error) { >> alert(`❌ 重启失败: ${error.message}`); >> } >> } >> >> function viewLogs(id) { >> const project = projects.find(p => p.id == id); >> window.open(`logs.html?project=${encodeURIComponent(project.name)}`, '_blank'); >> } >> >> // 初始加载 >> fetchProjectStatus(); >> >> // 定时更新数据 (每5秒) >> setInterval(fetchProjectStatus, 5000); >> </script> >> </body> >> </html> >> 所在位置 行:8 字符: 15 + --primary-color: #2c3e50; + ~ 一元运算符“--”后面缺少表达式。 所在位置 行:8 字符: 15 + --primary-color: #2c3e50; + ~~~~~~~~~~~~~~ 表达式或语句中包含意外的标记“primary-color:”。 所在位置 行:9 字符: 15 + --secondary-color: #3498db; + ~ 一元运算符“--”后面缺少表达式。 所在位置 行:9 字符: 15 + --secondary-color: #3498db; + ~~~~~~~~~~~~~~~~ 表达式或语句中包含意外的标记“secondary-color:”。 所在位置 行:10 字符: 15 + --success-color: #2ecc71; + ~ 一元运算符“--”后面缺少表达式。 所在位置 行:10 字符: 15 + --success-color: #2ecc71; + ~~~~~~~~~~~~~~ 表达式或语句中包含意外的标记“success-color:”。 所在位置 行:11 字符: 15 + --warning-color: #f39c12; + ~ 一元运算符“--”后面缺少表达式。 所在位置 行:11 字符: 15 + --warning-color: #f39c12; + ~~~~~~~~~~~~~~ 表达式或语句中包含意外的标记“warning-color:”。 所在位置 行:12 字符: 15 + --danger-color: #e74c3c; + ~ 一元运算符“--”后面缺少表达式。 所在位置 行:12 字符: 15 + --danger-color: #e74c3c; + ~~~~~~~~~~~~~ 表达式或语句中包含意外的标记“danger-color:”。 并未报告所有分析错误。请更正报告的错误并重试。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : MissingExpressionAfterOperator PS C:\Users\Administrator> # 1. 保存修复后的主脚本 >> $ecosystemManagerScript = Get-Content -Path "修复后的脚本内容" -Raw >> Set-Content -Path "E:\ProjectEcosystem\ProjectMonitor\Scripts\ProjectEcosystemManager.ps1" -Value $ecosystemManagerScript >> >> # 2. 创建仪表板目录 >> $dashboardDir = "E:\ProjectEcosystem\Dashboard" >> if (-not (Test-Path $dashboardDir)) { >> New-Item -ItemType Directory -Path $dashboardDir -Force >> } >> >> # 3. 保存仪表板文件 >> Set-Content -Path "$dashboardDir\index.html" -Value $dashboardHtml >> >> # 4. 安装服务(使用完整路径) >> & "E:\Install-EcosystemService.ps1" -Action Install >> >> # 5. 启动服务 >> Start-Service ProjectEcosystemManager >> >> # 6. 验证服务状态 >> Get-Service ProjectEcosystemManager >> Get-Content : 找不到路径“C:\Users\Administrator\修复后的脚本内容”,因为该路径不存在。 所在位置 行:2 字符: 27 + $ecosystemManagerScript = Get-Content -Path "修复后的脚本内容" -Raw + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (C:\Users\Administrator\修复后的脚本内容:String) [Get-Content], ItemNotFo undExce ption + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand 目录: E:\ProjectEcosystem Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2025/8/13 20:57 Dashboard 位于命令管道位置 1 的 cmdlet New-Service 请为以下参数提供值: BinaryPathName:
最新发布
08-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值