在 .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
告诉 zsh
将 params
的范围限制在函数内。
另一个解决方案是在调用函数时重置变量。
首先 -- 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
实例中的错误。
我的 .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
告诉 zsh
将 params
的范围限制在函数内。
另一个解决方案是在调用函数时重置变量。
首先 -- 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
实例中的错误。