在 .zshrc 中修改 youtube-dl 的问题

issue with a modification of youtube-dl in .zshrc

我的 .zshrc 中的代码是:

ytdcd () {  #youtube-dl that automatically puts stuff in a specific folder and returns to the former working directory after.
    cd ~/youtube/new/ && {
        youtube-dl "$@"
        cd - > /dev/null
    }
}
ytd() { #sofar, this function can only take one page. so, i can only send one youttube video code per line. will modify it to accept multiple lines..
    for i in $*;
        do
        params=" $params https://youtu.be/$i"
    done

    ytdcd -f 18 $params
}

所以,在命令行(终端)上,当我输入 ytd DFreHo3UCD0 时,我想下载位于 https://youtu.be/DFreHo3UCD0 的视频。问题是,当我连续输入命令时,系统只是尝试下载前一个命令的视频,并正确地声称下载完成。

例如输入:

> ytd  DFreHo3UCD0
> ytd  L3my9luehfU

不会尝试下载 L3my9luehfU 的视频,只会尝试下载 DFreHo3UCD0 的视频两次。

我会将 param 声明为 local,这样您就不会在 url 之后附加 url...

您可以尝试将这个很棒的功能添加到您的 .zshrc:

funfun() {
        local _fun1="$_fun1 fun1!"
        _fun2="$_fun2 fun2!"

        echo "1 says: $_fun1"
        echo "2 says: $_fun2"
}

观察事物;)

编辑(解释):

当采购 shell 脚本时,您将它添加到您当前的环境中,这就是为什么您可以 运行 您定义的那些功能。因此,当这些函数使用变量时,默认情况下,这些变量将是全局变量,并且可以从您环境中的任何地方访问!因此,在这种情况下,param 是针对您的 shell 会话的所有长度全局定义的。由于您希望同时下载多个视频,因此您将值附加到此全局变量,该变量会一直增长。

强制 local 告诉 zshparams 的范围限制在函数内。

另一个解决方案是在调用函数时重置变量。

首先 -- ytdcd 返回旧目录没有意义:您只能在子 shell 内更改到新目录,然后 exec youtube- dl 用应用程序替换那个 subshell:

这样出错的地方就更少了:中止函数的执行不会把东西留在错误的目录中,因为父 shell(您正在交互使用的那个)在第一个目录中从未更改过目录地点。

ytdcd () {
    (cd ~/youtube/new/ && exec youtube-dl "$@")
}

其次 -- 在构建参数列表时使用数组,而不是字符串。

如果您使用 set -x 来记录它的执行,您会看到您的原始命令 运行 类似于:

ytdcd -f 18 'https://youtu.be/one https://youtu.be/two https://youtu.be/three'

看到那些引语了吗?那是因为 $params 是一个 字符串 ,作为单个参数而不是数组传递。 (在 bash 中——或另一个 shell 遵循 POSIX 规则——不带引号的字符串扩展将被字符串拆分和全局扩展,但 zsh 不会 遵循 POSIX 规则)。

下面构建了一个单独的参数数组并单独传递它们:

ytd() {
    local -a params=( )
    local i

    for i; do
        params+=( "https://youtu.be/$i" )
    done

    ytdcd -f 18 "${params[@]}"
}

最后,您 实际上 并不打算将所有 URL 传递给一个 youtube-dl 实例。要 运行 每个 URL 一个单独的实例,请使用:

ytd() {
    local i retval=0
    for i; do
        ytdcd -f 18 "$i" || retval=$?
    done
    return "$retval"
}

请注意,我们正在捕获非成功退出状态,以便不隐藏除最后一个(否则会发生)以外的任何 ytdcd 实例中的错误。