我遇到了问题:现有工具正在调用ffmpeg -i path to file -f wav -ar 16000 ...
但它无法逃脱路径。 (它应该是ffmpeg -i path\ to\ file -f ...
修复工具或它产生的路径并非易事。
所以我的想法是创建一个名为ffmpeg
的小脚本,将它放在真正的ffmpeg之前的$ PATH上,并在修复它们之后转发参数。 "修复它们"意味着将${2}
连接到${n-1}
,其中${n}
是跟随路径的-f
参数。
但是我怎么写这个循环? This answer循环遍历所有参数,我可能会检测到该循环中的-f
参数,但是如何重新组合真正的ffmpeg进程的命令行呢?
答案 0 :(得分:1)
你真的需要报告这是一个错误,这是一个令人尴尬的初学者的错误,并不难解决。
无论如何,这里有一个kludge:
#!/bin/bash
array=()
start="-i"
stop="-f"
fileArg=0
for param
do
if [[ $fileArg = 1 ]]
then
if [[ $param = $stop ]]
then
fileArg=0
array+=("${file% }" "$param")
fi
file+="$param "
else
[[ $param = $start ]] && fileArg=1
array+=("$param")
file=""
fi
done
printf "Your broken tool provided these argument:\n"
printf "%q " "$@"
printf "\n\n"
printf "Tried to salvage it by turning it into:\n"
printf "%q " "${array[@]}"
printf "\n"
/path/to/real/ffmpeg "${array[@]}"
这里的示例输出:
$ ./ffmpeg -i path to file -f wav -ar 16000
Your broken tool provided these argument:
-i path to file -f wav -ar 16000
Tried to salvage it by turning it into:
-i path\ to\ file -f wav -ar 16000
这并不适用于所有情况 - 没有好办法重新组合已拆分为shell字的文件名。这种方法可以打破连续的多个空格,全局,大括号扩展,引号,美元,反引号等。如果文件名中有不匹配的引号或括号,该工具很可能甚至无法调用ffmpeg(或此替换)。
作为一个很好的功能,如果该工具被修复,这个脚本将是一个无操作(假设文件名仍在-i和-f之间)
答案 1 :(得分:1)
如果您能够使用awk
,sed
或类似的东西将未引用的命令传递给函数,则可以修复引用或在路径为时将其转义总是在同样的两个选项中:
#!/bin/env bash
# quote_path.sh
# wraps quotes or escapes an unquoted path in a command
# takes command with unquoted path and wraps in quotes
quoted_cmd()
{
quoted=$(echo $cmd | awk '{ sub(/ -f/,"\" -f"); sub(/-i /,"-i \""); print }')
# eval $quoted
escape_cmd # comment out if using eval $quoted
}
# takes quoted_cmd() and escapes it (as an alternative to wrapping in quotes)
escape_cmd()
{
escape=$(echo $quoted | awk 'BEGIN { FS="-i \"|\" -f" } ; { print $2 }')
concat=$(echo $escape | sed 's! !\\\\ !g')
cmdesc=$(echo $quoted | awk '{ sub(/".*" -f/," -f"); $2="-i '"${concat}"'"; print }')
eval $cmdesc
}
cmd="$@"
quoted_cmd
因此,您可以将您的命令作为参数传递(作为字符串或变量):
$ ./quote_path.sh ffmpeg -i /path to file /path to file -f wav -ar 16000 "foobar" ...
作为 Etan Reisner 和,其他人提到,它应该被报告为一个错误,同时它就是它...试一试!
更新:我能够稍微修改一下这个函数,以便在命令的另一部分有带引号的参数,包含其他斜杠等的情况下失败的可能性更小。该命令在将其作为参数传递(可选)时不应要求引用,并且将在命令中生成带引号或转义路径。调用该函数后,返回整个路径,并与命令的其余部分连接。
<强>结果:强>
ffmpeg -i "/path to file /path to file" -f wav -ar 16000 ... # quoted_cmd()
ffmpeg -i /path\ to\ file\ /path\ to\ file -f wav -ar 16000 ... # escape_cmd()
...
ffmpeg version 2.5.3-tessus Copyright (c) 2000-2015 the FFmpeg developers
...