我的.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的视频。
答案 0 :(得分:2)
首先 - 没有必要返回ytdcd
的旧目录:您只能在子shell中更改为新目录,然后使用exec
youtube-dl替换该子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 - 不带引号的字符串扩展将是字符串拆分和全局扩展,但是zsh 不遵循POSIX规则。)
以下构建一个单独的参数数组并单独传递它们:
ytd() {
local -a params=( )
local i
for i; do
params+=( "https://youtu.be/$i" )
done
ytdcd -f 18 "${params[@]}"
}
最后,提示您实际打算不将所有网址传递给一个youtube-dl
实例。要按URL运行单独的实例,请使用:
ytd() {
local i retval=0
for i; do
ytdcd -f 18 "$i" || retval=$?
done
return "$retval"
}
请注意,我们正在捕获非成功退出状态,以免在最后一个ytdcd
实例中隐藏错误(否则会发生错误)。
答案 1 :(得分:1)
我会将param
声明为local
,以便您不会在网址后附加网址...
您可以尝试将此强大的功能添加到.zshrc
:
funfun() {
local _fun1="$_fun1 fun1!"
_fun2="$_fun2 fun2!"
echo "1 says: $_fun1"
echo "2 says: $_fun2"
}
观察事物;)
编辑(解释):
在获取shell脚本时,您将其添加到当前环境中,这就是您可以运行您定义的那些功能的原因。因此,当这些函数使用变量时,默认情况下,这些变量将是全局的,并且可以从您环境中的任何位置访问!因此,在这种情况下,{shell}会话的所有长度都会全局定义param
。由于您希望允许一次下载多个视频,因此您要将值附加到此全局变量,该变量将一直增长。
执行local
告诉zsh
将params
的范围仅限于此功能。
另一种解决方案是在调用函数时重置变量。