我正在尝试学习(没有编程背景)创建一些自定义 bash 脚本来从 Nautilus 转换选定的文件,但我遇到了一个我无法理解的问题。
作为参考,这是一个确实有效的脚本。它将选定的 .MP4 文件转换为 .mkv、复制时间戳并向用户打印一些反馈。
#!/bin/bash
for i in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
do
ffmpeg -i "$i" -movflags use_metadata_tags -c:v libx265 -crf 26 -preset slow -c:a aac -b:a 160k "${i%.*}.mkv" && touch -r "$i" "${i%.*}.mkv" && notify-send "Converted '$(basename "$i")'" || notify-send "Failed converting '$(basename "$i")'"
done
notify-send "Conversion finished"
现在,这是一个不起作用的脚本。它应该将选定的 .m4a 文件转换为 .mp3,添加封面图像和一些标签,复制时间戳并向用户提供一些反馈。
#!/bin/bash
for i in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
do
ffmpeg -i "$i" "${i%.*}.mp3" && eyeD3 -a "Author" -A "Album" --add-image="cover.jpg":FRONT_COVER "${i%.*}.mp3" && touch -r "$i" "${i%.*}.mp3" && notify-send "Converted '$(basename "$i")'" || notify-send "Failed converting '$(basename "$i")'"
done
notify-send "Conversion finished"
当我运行这个时,我收到多个错误,提示“转换失败(文件路径的一部分)”...对于文件路径的某些部分,例如文件夹和文件名的部分。
我不确定我在这里做了什么不同的事情。我使用相同的$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
参数,但它在第二个脚本中的工作方式不同。
作为参考,这个其他脚本与第二个脚本相同,但适用于文件夹中的所有文件,确实可以完美工作,所以我确信里面的命令do
可以工作。
#!/bin/bash
for i in *.m4a
do
ffmpeg -i "$i" "${i%.*}.mp3" && eyeD3 -a "Author" -A "Album" --add-image="cover.jpg":FRONT_COVER "${i%.*}.mp3" && touch -r "$i" "${i%.*}.mp3" && notify-send "Converted '$(basename "$i")'" || notify-send "Failed converting '$(basename "$i")'"
done
notify-send "Conversion finished"
我缺少什么? only可以$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
处理某些文件类型吗?问题是在其他地方吗?
答案1
这就是我重写失败脚本的方法。我无法测试它,但我担心的是脚本运行的目录不清楚。真的存在吗cover.jpg
?
值得notify-send "$PWD"
在顶部附近添加一个来检查脚本是否正在从预期目录运行。如果不是,那么也许可以从正在处理的值推断出相关目录$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
(您可能需要更改"cover.jpg"
为"${src%/*}/cover.jpg"
)。
#!/bin/bash
count=0 success=0
# Transform command line arguments (if provided)
[[ -z "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" ]] &&
NAUTILUS_SCRIPT_SELECTED_FILE_PATHS=$(printf "%s\n" "$@")
# Process each file in turn
while IFS= read -r src
do
# Target
dst="${i%.*}.mp3"
# Primary conversion to mp3
step=0
ffmpeg -i "$src" "$dst" && ((step++))
# Add album cover (if available)
if [[ step -eq 1 ]]
then
if [[ -f "cover.jpg" ]]
then
eyeD3 -a "Author" -A "Album" --add-image="cover.jpg":FRONT_COVER "$dst" && ((step++))
else
((step++))
fi
fi
# Reset the timestamp
if [[ step -eq 2 ]]
then
touch -r "$src" "$dst" && ((step++))
fi
# Notify the user
if [[ step -eq 3 ]]
then
notify-send "Converted '${src##*/}'"
((success++))
else
notify-send "Failed converting '${src##*/}' at step $step"
fi
# Count it
((count++))
done <<<"$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS"
[[ count -gt 1 ]] &&
notify-send "Conversion finished ($success files of $count)"
exit $((count - success))
您可能可以notify-send
使用类似的方法来保护呼叫[[ -n "$DISPLAY" ]] && notify-send …
,但我不能完全确定。然后,这将允许您at
使用命令行参数从批处理(例如,)运行脚本。