我正在尝试为 yt-dlp 创建一个 shell 脚本,该脚本将 URL 作为来自命令行的输入,或者如果没有给出输入,则使用内部列表。该脚本在给定输入时有效,但在未给出输入并因此使用内部列表时崩溃。
#!/usr/bin/env bash
URLfromTerminal="$1"
PathToList="--batch-file '${HOME}/bin/ytdlp/Lists/Test.txt'"
[[ -z "$URLfromTerminal" ]] && Download="$PathToList" || Download="$URLfromTerminal"
yt-dlp -ciw \
-S "res:1920" \
--ffmpeg-location "$HOME"/bin/ffmpeg/ffmpeg \
"$Download"
未给出输入并使用内部列表时出现错误消息:
yt-dlp: error: no such option: --batch-file '/Users/UserName/bin/ytdlp/Lists/Test.txt'
当从变量扩展时,为什么 yt-dlp 将文本文件的路径视为选项?
我是 shell 脚本新手,不知道什么是最佳实践,所以任何一般性的改进也是受欢迎的。
答案1
你的问题有两个方面:
- 您在假定保存文件名的字符串中包含文字引号。由于引号不是文件名的一部分,因此不应将它们包含在字符串中。
--batch-file
您可以在保存文件路径名的字符串中包含该选项。这迫使您依赖 shell 来正确拆分未加引号的变量扩展。由于您引用了 的扩展$Download
,因此 shell 不会分割字符串,并且整个字符串将用作单个参数。
#!/bin/sh
if [ -n "$1" ]; then
printf '%s\n' "$1"
else
cat ~/bin/ytdlp/Lists/Test.txt
fi |
yt-dlp -ciw \
-S res:1920 \
--ffmpeg-location ~/bin/ffmpeg/ffmpeg \
-a -
这使用简单的测试来检测第一个参数是否为空-n
。如果它不为空,则将其传递给printf
to ,后者将使用(与 相同)yt-dlp
读取它。如果它是空的,您的文本文件将通过.-a -
--batch-file -
yt-dlp
cat
以更类似于您尝试的方式解决它:
#!/bin/sh
if [ -z "$1" ]; then
set -- -a ~/bin/ytdlp/Lists/Test.txt
fi
yt-dlp -ciw \
-S res:1920 \
--ffmpeg-location ~/bin/ffmpeg/ffmpeg \
"$@"
这会将脚本的参数列表传递给yt-dlp
if$1
为非空。否则,它会在使用之前将参数列表设置为-a
文本文件的路径名那在呼叫中yt-dlp
。
这将允许您在脚本的命令行上传递任意数量的附加参数,而不仅仅是一个 URL。
答案2
看看你引用了什么!您试图传递两个参数字符串,即
--batch-file
和
'/Users/UserName/bin/ytdlp/Lists/Test.txt'
作为一个论点,
"--batch-file '/Users/UserName/bin/ytdlp/Lists/Test.txt'"
例如,yt-dlp 知道一个被调用的参数(即它知道如何解释参数字符串)--batch-file
,就像它知道一样--help
,但它不知道--batch-file '/Users/UserName/bin/ytdlp/Lists/Test.txt'
。
只是你的最后一行没有围绕"
。$Download
答案3
一般是更安全、更好到引用 shell 变量。然而,在这种情况下,正是引号破坏了您的脚本,因为引号"--batch-file '${HOME}/bin/ytdlp/Lists/Test.txt'"
是作为单个参数传递的,而不是作为一个标志及其值传递的。仍然允许您使用任意文件名的最简单的解决方案是仅将路径放入变量中,而不是选项中:
#!/usr/bin/env bash
URLfromTerminal="$1"
PathToList="$HOME/bin/ytdlp/Lists/Test.txt"
if [[ -z "$URLfromTerminal" ]]; then
DownloadFlag="--batch-file"
DownloadPath="$PathToList"
else
DownloadPath="$URLfromTerminal"
fi
yt-dlp -ciw \
-S "res:1920" \
--ffmpeg-location "$HOME"/bin/ffmpeg/ffmpeg \
"$DownloadFlag" "$DownloadPath"
当 为$DownloadFlag
空时,它将简单地作为空字符串传递,因此该命令仍然有效。
使用空格传递参数的标准安全方法是使用数组。因此,您可能也想研究该选项,因为对于更复杂的情况,它是必要的:
#!/usr/bin/env bash
URLfromTerminal="$1"
PathToList="$HOME/bin/ytdlp/Lists/Test.txt"
if [[ -z "$URLfromTerminal" ]]; then
DownloadPath=( "--batch-file" "$PathToList")
else
DownloadPath=( "$URLfromTerminal" )
fi
yt-dlp -ciw \
-S "res:1920" \
--ffmpeg-location "$HOME"/bin/ffmpeg/ffmpeg \
"${DownloadPath[@]}"