Powershell Core,MXLinuxv21,运行 linux /usr/bin/x 命令会导致对象命令在 "no file found"



我有一个powershell脚本,包含三个部分:1。修改文件名以删除MicrosoftOS保留字符;2.运行/usr/bin/flac将*.wav文件转换为*.flac,3。使用.dll将ID3标记从*.mp3文件复制到*.flac文件。

这个脚本的所有三个部分都在我以前的Kubuntu v222.10系统上运行。在MXLinux v21上,此脚本在步骤2失败。错误是";找不到文件";对于/usr/bin/flac命令的对象/usr/bin/flac加载,但表示找不到指定给它的文件。步骤1和3有效(我知道这一点,因为脚本需要一个参数来跳过步骤2;因此,如果*.wav文件已经是*.flac文件,我可以运行它,例如,在上一次运行中,步骤2成功,但由于某种原因,步骤3失败)。

这是PS代码片段:

[string] $flacEXE = '/usr/bin/flac'
if($convert -eq "yes" || $convert -eq "Yes" || $convert -eq "YES") 
{
if (Test-Path -Path "$workingPath/*cr.wav")
{ 
$CRFiles = Get-ChildItem -Path "$workingPath/*cr.wav"
foreach ($crFile in $CRFiles)
{
$output = & $flacEXE "`"$crFile`""
if ($LASTEXITCODE -ne 0) 
{
Write-Host "The flac conversion created an error..." -ForegroundColor Red
Write-Host "$output" -ForegroundColor Red
}
}
}
else 
{
Write-Host "No ClickRepair files found but Convert was Yes ... Aborting script.`n" -ForegroundColor Red
throw $_.Exception.Message
exit      
}
}

如果我在powershell中的提示符下运行/usr/bin/flac(例如,在Visual Studio代码中),它将失败。如果我从linux终端在同一文件夹中的同一文件上运行/usr/bin/flac,它就可以工作了。

我认为这一定是某种权限问题(范围问题?),但无法解决。这些文件位于/mnt/上安装的NTFS USB卷上。我最近迁移到MXLinux,因此重新创建了我的系统。这是我第一次使用这个powershell脚本。

我应该注意的是,Set ExecutionPolicy的一致性在Linux上对Powershell Core无效,只在Windows系统上有效,所以这没有用。

替换:

$output = & $flacEXE "`"$crFile`""

带有:

$output = & $flacEXE $crFile
  • 与POSIX兼容shell(如bash)不同,您不需要在PowerShell中的"..."中包含作为参数传递的变量引用-PowerShell没有与POSIX兼容性shell的所谓shell扩展等效的功能,尤其是没有分词;因此,带有空格的值不需要在PowerShell中使用"..."进行保护。

  • "`"$crFile`""之所以有效,只是因为PowerShell如何将嵌入双引号的参数传递给外部程序(直到PowerShell 7.2.x)的长期错误

    • 在PowerShell 7.3.0中,此错误已修复,因此上面的内容现在(正确地)将内部"作为参数的逐字部分传递给目标程序。(然而,"$crFile"在7.2.x及更高版本中都可以工作,尽管"仍然是不必要的,如上所述)。

    • 请参阅此答案以获取更多信息,包括如何为了向后兼容性而选择旧的、已损坏的行为。还要注意的是,当前的计划是继续默认仅在类Unix平台上为新的、正确的行为,并且在Windows7.3.1之后的某个版本上的可能会默认恢复到旧的、坏的行为,新的、错误的行为需要选择加入


顺便说一句,关于if($convert -eq "yes" || $convert -eq "Yes" || $convert -eq "YES"):

  • if($convert -eq "yes" || $convert -eq "Yes" || $convert -eq "YES")替换为if ($convert -eq 'yes')-默认情况下,PowerShell不区分大小写[1]如果必须使用多个操作,则需要将它们与-or链接,而不是与||-||操作命令的成功状态,而不是操作;例如:

    • $true || 'never get here'$false || 'never get here'不会触发||的RHS,因为$true$false都是成功执行的表达式,而不管它们的值如何,因此不会触发||管道链运算符的RHS(类似于&&)。

    • 对于基于的操作(表达式返回值出),我们使用-or、逻辑-or-and运算符。


[1]对于区分大小写的行为,使用前缀为c的操作数变体,如-eq;例如'FOO' -ceq 'foo'$false。类似地,默认情况下,大多数标准cmdlet和switch语句不区分大小写,并提供-CaseSensitive开关作为opt-in

相关内容

  • 没有找到相关文章