Powershell 获取不在括号中的内容-进程访问被拒绝

Powershell 获取不在括号中的内容-进程访问被拒绝,powershell,Powershell,使用“获取内容”从文件中删除空白时: $file = "C:\Folder\MyFile001.txt" Get-Content -Path $file | ? { -not [string]::IsNullOrWhiteSpace($_) } | Set-Content -Path $file 显示错误消息“Set Content:进程无法访问文件”…,因为另一个进程正在使用该文件 修复方法是将括号与Get Content一起使用: 这是什么原因?我想了解括号之间的区别,以及这是否适用于其他

使用“获取内容”从文件中删除空白时:

$file = "C:\Folder\MyFile001.txt"
Get-Content -Path $file | ? { -not [string]::IsNullOrWhiteSpace($_) } | Set-Content -Path $file
显示错误消息“Set Content:进程无法访问文件”…,因为另一个进程正在使用该文件

修复方法是将括号与Get Content一起使用:


这是什么原因?我想了解括号之间的区别,以及这是否适用于其他cmdlet。

括号在Powershell中的工作方式与在代数中的工作方式相同

有点

PowerShell首先执行括号中的命令,然后尝试将其键入匹配到任何位置。在本例中,您告诉它在继续执行下一个命令之前完成运行Get Content并将缓冲区读入内存,而不是通过管道流传输所有内容

这类似于BaSH的工作方式,您可以使用类似于假定service.txt包含一行内容的内容来表示apache:

Service $(cat /etc/service.txt) Stop
>> Service apache stop 
它将以$执行命令,并在运行命令的其余部分之前将其作为文本返回

在PowerShell中,您可以使用括号的类型匹配功能完成一些简单的操作,例如使其仅返回单个对象属性:

(Get-ChildItem -filter "*.pdf" -Path .\Projects).FullName 
>> C:\Users\ncf\Projects\Documentation.pdf

当cmdlet在管道上输出某些内容时,将在处理cmdlet的下一个输出之前执行管道。因此,当字符串沿着管道向下运行以设置内容时,Get Content仍然处于活动状态,输出文件处于打开状态,等待轮到它继续执行。但是,当您包装表达式时,所有输出都被收集到一个数组中,然后将该数组下推到管道中。获取内容已完成,文件已关闭。为了演示,考虑这个函数:

function get-10dates { $count = 0; while($count -lt 10){ get-date; $count += 1 }}
运行它并将其输送到foreach循环时:

由于foreach中的睡眠,您将获得以下输出,每个日期延迟一秒钟:

# ~> get-10dates | foreach { $_; sleep -Seconds 1 }

June 19, 2019 9:58:36 AM
June 19, 2019 9:58:37 AM
June 19, 2019 9:58:38 AM
June 19, 2019 9:58:39 AM
June 19, 2019 9:58:40 AM
June 19, 2019 9:58:41 AM
June 19, 2019 9:58:42 AM
June 19, 2019 9:58:43 AM
June 19, 2019 9:58:44 AM
June 19, 2019 9:58:45 AM
现在,如果您将函数包装在中。您可以看到,所有10个日期都是在1秒钟内一次创建的,然后才通过管道传递:

# ~> (get-10dates) | foreach { $_; sleep -Seconds 1 }

June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
# ~> get-10dates | foreach { $_; sleep -Seconds 1 }

June 19, 2019 9:58:36 AM
June 19, 2019 9:58:37 AM
June 19, 2019 9:58:38 AM
June 19, 2019 9:58:39 AM
June 19, 2019 9:58:40 AM
June 19, 2019 9:58:41 AM
June 19, 2019 9:58:42 AM
June 19, 2019 9:58:43 AM
June 19, 2019 9:58:44 AM
June 19, 2019 9:58:45 AM
# ~> (get-10dates) | foreach { $_; sleep -Seconds 1 }

June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM
June 19, 2019 9:58:53 AM