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

在我以前的Kubuntu v22.10系统上,这个脚本worked的所有三个部分.在MXLinuxv21上,此脚本在步骤2失败.对于/usr/bin/flac命令的objects,错误为"未找到文件"./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(例如,在Visual Studio代码中)的提示符下运行/usr/bin/flac,它将失败.如果我从Linux终端对同一文件夹中的相同文件运行/usr/bin/flac,它会正常工作.

我认为这一定是某种权限问题(作用域问题?),但无法弄清楚.这些文件位于装载在/mnt/上的NTFS USB卷上.我最近迁移到了MXLinux,因此重新创建了我的系统.这是我第一次使用这个PowerShell脚本.

我应该指出,Set-ExecutionPolicy的一致性对于Linux上的PowerShell Core是无效的,只在Windows系统上有效,所以这是没有用的.

推荐答案

替换:

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

有:

$output = & $flacEXE $crFile
  • bash等POSIX兼容的shell 不同,you do not need to enclose variable references passed as arguments in 101 in PowerShell-PowerShell没有与POSIX兼容的shell 的所谓shell 扩展类似功能,特别是没有分词;因此,在PowerShell中,带空格的值不需要使用"..."进行保护.

  • That 100 worked at all is only due to a longstanding bug介绍PowerShell如何将带有embedded个双引号的参数传递到external programs,直到PowerShell 7.2.x.

    • 在PowerShell 7.3.0中,此错误已修复,因此上述代码现在(正确地)将内部" as a a verbatim part of the argument传递给目标程序.(但是,"$crFile"可以在7.2.x和更高版本中使用,但如上所述,"仍然是不必要的).

    • 有关更多信息,请参见this answer,包括如何为了向后兼容而 Select 使用旧的、不完整的行为.还要注意的是,目前的计划是继续从default到新的、仅在类Unix平台上正确的行为,on Windows某些版本after 7.3.1可能会恢复到旧的、坏的行为by default,而新的、正确的行为需要opt-in.


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

  • if($convert -eq "yes" || $convert -eq "Yes" || $convert -eq "YES")替换为101-PowerShell is case-insensitive by default.[1]如果必须使用multiple operations, you need to chain them with 102, not with 103-||操作success status of commands,而不是values;例如:

    • $true || 'never get here'$false || 'never get here'确实not触发||的RHS,因为$true$false都是execute successfullyirrespective of their value的表达式,因此Do not触发|| pipeline-chain operator的RHS(类似于&&).

    • 对于基于values(表达式return values或命令output)的运算,使用-orlogical -or and -and operators.


[1]对于CASE-sensitive行为,使用操作数的c前缀变体,例如-eq;例如,'FOO' -ceq 'foo'$false.同样,大多数标准cmdlet和switch语句默认情况下不区分大小写,并将-CaseSensitiveswitch 设置为opt-in.

Linux相关问答推荐

当页面对齐关闭时,x86—64上的对象中的成员初始化器的Clang代码生成错误?

使用 awk 从文件中检索一组特定的字符串

如何在 Linux 上使用 Python 判断进程是否仍在运行?

如何在 Linux 中向应用程序发出信号而不杀死它?

在 Bash 中从最后到第一个输出文件行

如何在 shell 脚本中动态生成新的变量名?

我如何从 Ubuntu 上的源代码自己构建 python?

size_t 和 off_t 的用法有什么区别?

分段故障处理

带有 curl 的 Linux 脚本来判断 Web 服务是否已启动

NGINX:connect() 到 unix:/var/run/php7.0-fpm.sock 失败(2:没有这样的文件或目录)

如何以另一个用户的身份使用 sudo 在 bash 子shell 中执行一系列命令?

在 Emacs 中匹配括号的命令是什么?

从命令行导入 PostgreSQL CSV

以原子方式移动目录

如何运行时调试共享库?

Linux SCHED_OTHER、SCHED_FIFO 和 SCHED_RR - 区别

svn over HTTP 代理

如何停止 Linux 上的不间断进程?

Bash:等待超时