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

Scripting 在.zshrc中修改youtube dl的问题,scripting,zsh,zshrc,youtube-dl,Scripting,Zsh,Zshrc,Youtube Dl,我在.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

我在.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时,我希望在下载视频。问题是,当我连续输入命令时,系统只是尝试下载前一个命令的视频,并正确地宣称下载已完成

例如,输入:

> ytd  DFreHo3UCD0
> ytd  L3my9luehfU

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

我将声明
参数
本地
,这样您就不会在url之后附加url

您可以尝试将这个很棒的函数添加到
.zshrc

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

        echo "1 says: $_fun1"
        echo "2 says: $_fun2"
}
观察事物;)

编辑(解释):

当寻找shell脚本时,您可以将其添加到当前环境中,这就是为什么您可以运行您定义的那些函数。因此,默认情况下,当这些函数使用变量时,这些变量将是全局的,并且可以从环境中的任何位置访问!因此,在本例中,
param
是为shell会话的所有长度全局定义的。由于您希望允许同时下载多个视频,因此将向该全局变量添加值,该值将一直增长

强制执行
local
告诉
zsh
params
的范围仅限于函数

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

首先--没有必要为
ytdcd
返回旧目录:您只能在子shell内更改到新目录,然后
exec
youtube dl以应用程序进程替换该子shell:

这样可以减少出错的次数:中止函数的执行不会将内容留在错误的目录中,因为父shell(您交互使用的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中——或者在遵循POSIX规则的另一个shell中——无引号的字符串扩展将是字符串拆分和glob扩展,但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
实例中隐藏除最后一个(否则会发生)之外的错误。

看起来不错,我现在正在测试它。你能简单解释一下发生了什么吗?完成了,我希望这对你有帮助。我不得不说,一开始我不知道该怎么看待这个问题!我不得不查看youtube dl的文档。。。检查一下你的视频:这里花括号的用法是什么?我可以看出,在MacOSX上删除它们效果很好。没有特别的原因,我喜欢用它们来分隔变量@nyxee,……顺便说一句——如果你是那种通过实验来找出问题的人,看看什么是有效的,让我敦促你不要在实验中使用zsh——它可以让你摆脱很多在其他地方表现不好的事情,因此,当您在处理在非zsh shell中执行的代码时,很容易养成产生bug的习惯。(另外,了解角落案例的位置也很有价值——空格包围的通配符、文本换行符或文件名中的引号等——包括测试案例中的内容)。bash和zsh彼此不兼容。不要在外壳之间交叉标记;只为您实际使用的shell标记。事实上,我很惊讶它对zsh也没有错误。具有多个URL的
ytd
在实践中是否确实有效?看起来它应该传递一个字符串,所有URL空间分隔为
ytdcd
,而不是每个原始参数传递一个参数。(…后续:测试已经证实了这一点;
(set-x;ytd一两三)
发出最后一个命令
ytdcd-f 18'https://youtu.be/one https://youtu.be/two https://youtu.be/three“
,将所有三个URL混在一起传递到一个参数中,而不是每个URL单独传递一个参数)。我的目标是能够发送
ytd一二三
,最终得到
ytdcd一&&ytdcd二&&ytdcd三
。我认为@jraynal提供的解决方案最初的运气导致了这个问题。现在应该可以很容易地修改它来处理这种情况。我将对此进行改进,并看到调用
ytd1233
会连续下载三个视频,这意味着它可以方便地调用
ytdcdOne&&ytdcdTwo&&ytdcdTwo
。也许您可以提供完整的解决方案。@nyxee,…因此,如果
youtube dl
在一个命令行上接受多个URL(当作为完全独立的参数传递时),上面已经涵盖了它。如果没有,那么您将希望将
ytdcd
移动到
for
循环中,如果您的意思是想要
&
&
的效果,那么可能需要使用
| break
中断。当您在示例中使用它时,这就是您所要求的……也就是说,我已经修改了答案,以明确说明我的建议。@nyxee,请不要编写技术术语格式的代码,而不是实际代码。但是,您完全可以将它们放在并行运行的不同进程中。就个人而言,我会使用GNUxargs:
printf'%s\0'${params[@]}”|(cd~/youtube/new&&execxargs-p8-n1youtube-dl)
a