向'提供Powershell参数;启动';违反命令?
我有一个PowerShell脚本,它调用ffmpeg对当前文件夹中的所有.mp4视频文件进行两次编码向'提供Powershell参数;启动';违反命令?,powershell,Powershell,我有一个PowerShell脚本,它调用ffmpeg对当前文件夹中的所有.mp4视频文件进行两次编码 foreach ($i in Get-ChildItem . | Where { $_.extension -like ".mp4" }) { ffmpeg -y -i "$i" -c:v libx265 -b:v 2.2M -preset medium -x265-params pass=1 -an -f mkv NUL ffmpeg -i "$i" -c:v libx265 -b:v
foreach ($i in Get-ChildItem . | Where { $_.extension -like ".mp4" }) {
ffmpeg -y -i "$i" -c:v libx265 -b:v 2.2M -preset medium -x265-params pass=1 -an -f mkv NUL
ffmpeg -i "$i" -c:v libx265 -b:v 2.2M -x265-params pass=2 -c:a libopus -ac 1 -b:a 64k -preset medium "small\$i.mkv"
}
它工作得很好,但在使用时会使我的系统停止,所以我想给ffmpeg进程一个低优先级和一个仅允许它们使用两个CPU核的关联。所以我试着
foreach ($i in Get-ChildItem . | Where { $_.extension -like ".mp4" }) {
start "x265ify" /wait /low /b /affinity C ffmpeg -y -i "$i" -c:v libx265 -b:v 2.1M -preset medium -x265-params pass=1 -an -f mkv NUL
start "x265ify" /wait /low /b /affinity C ffmpeg -i "$i" -c:v libx265 -b:v 2.1M -x265-params pass=2 -c:a libopus -ac 1 -b:a 64k -preset medium "small\$i.mkv"
}
这不起作用,因为-i
被认为是不明确的。因此,我尝试将整个命令(“ffmpeg-y-I…”“
forward”)放在一个字符串中,引号被转义。这不起作用,因为找不到接受/low
的位置参数。我尝试忽略这一点,将命令作为一个单独的变量传递,我尝试的任何东西似乎都不起作用
但我有一个Ruby脚本,它调用ffmpeg的方式与实际工作方式完全相同。上面写着
start "x265-ifier" /wait /low /b /affinity #{AFFINITY} ffmpeg \
-hide_banner \
-i "#{v}" \
-vf scale=-2:#{HEIGHT} \
-c:a libopus \
-b:a #{AUDIO_BITRATE}k \
-ac 1 \
-c:v libx265 \
-x265-params vbv-maxrate=#{MAX_VIDEO_BITRATE}:vbv-bufsize=7000 \
-preset #{PRESET} \
-crf #{CRF} \
"#{dest}" \
-y
那么我做错了什么?为什么PowerShell不想运行这个命令,如果Ruby是中间人,这个命令可以正常运行?为什么
/low
在文档中作为一个参数列出时不是一个参数,并且当传递给start
的整个字符串被认为是它正在运行的命令,并且-I
是该命令的一个有效参数时,我如何使-I
不那么模棱两可 在PowerShell中,start
是cmdlet[1]的内置别名,其语法和行为不同于cmd.exe的内部start
命令
要调用后者[1],必须显式调用cmd.exe
,如下所示:
cmd /c start `"x265ify`" /wait /low /b /affinity C ffmpeg -y -i $i -c:v libx265 -b:v 2.1M -preset medium -x265-params pass=1 -an -f mkv NUL
注:
“
字符x265ify
被转义为`
,以确保它们被传递到start
,后者(笨拙地)使用它们来区分表示窗口标题的第一个参数与要调用的命令
$i
不必双重报价,因为PowerShell会根据需要进行报价
- 使用
/wait
意味着第二个start
命令在第一个命令完成之前不会被调用
顺便说一句:PowerShell对空参数(“
)和带有嵌入式“
字符的参数的处理。从PowerShell[Core]7.0开始,传递到外部程序的参数从根本上被破坏,需要笨拙的解决方法-有关更多信息,请参阅
[1] 使用Get命令start
来发现这个事实
[2] 这在您的情况下是必需的,因为Start Process
不提供对已启动进程的优先级或CPU相关性的控制。在PowerShell中,Start
是cmdlet[1]的内置别名,其语法和行为不同于cmd.exe
的内部Start
命令
要调用后者[1],必须显式调用cmd.exe
,如下所示:
cmd /c start `"x265ify`" /wait /low /b /affinity C ffmpeg -y -i $i -c:v libx265 -b:v 2.1M -preset medium -x265-params pass=1 -an -f mkv NUL
注:
“
字符。大约x265ify
被转义为`
,以确保它们被传递到start
,后者(笨拙地)使用它们来区分表示窗口标题的第一个参数和要调用的命令
$i
不必双重报价,因为PowerShell会根据需要进行报价
- 使用
/wait
意味着第二个start
命令在第一个命令完成之前不会被调用
顺便提一下:PowerShell处理空参数(“
)和嵌入“
字符的参数。从PowerShell[Core]7.0开始,传递到外部程序的操作从根本上被破坏,需要笨拙的解决方法-有关更多信息,请参阅
[1] 使用Get命令start
来发现这个事实
[2] 这在您的情况下是必要的,因为启动进程
不能控制启动进程的优先级或CPU相关性。很高兴听到这个消息,@GreenTriangle。请参阅我的更新,它描述了如何将命令识别为别名,以及在将参数传递给外部程序时可能出现问题的帖子链接。很高兴听到这个消息,@GreenTriangle。请参阅我的更新,它描述了如何将命令标识为别名,并链接到向外部程序传递参数时可能出现问题的帖子。