我想创建一个运行如下的函数:
youtube-dl -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best' "https://www.youtube.com/watch?v=_OBlgSz8sSM"
目前,在 .zshrc 中,我一直在尝试
downloadyoutube(){
youtube-dl -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best' "$1"
但它仍然希望我在调用它时在 URL 周围添加引号。
相反,我想跑
downloadyoutube https://www.youtube.com/watch?v=_OBlgSz8sSM
不带引号。
并不是
downloadyoutube "https://www.youtube.com/watch?v=_OBlgSz8sSM"
有没有办法做到这一点?
答案1
正如拘萨罗南达(Kusalananda)所说,noglob
这是要走的路;您可以按原样定义您的函数,然后使用alias
include noglob
:
downloadyoutube(){
youtube-dl -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best' "$1"
}
alias downloadyoutube="noglob downloadyoutube"
不管怎样,你试图用这些论点做什么是没有意义的:youtube-dl
默认它已经很多年了;阅读当前man
页面!
我想强调的是,库萨拉南达是对的:
- 您甚至
'
不仅需要"
在这里,以免您希望一些特殊字符成为问题, - 即使关闭通配符也无助于防止事件/重定向字符;由于每个 Youtube URL 都会包含
&
,您最好将 shell 配置为自动将&
字符串中粘贴的内容(而不是在行尾)替换为\&
;我的 zsh 会自动执行此操作,我认为这应该归咎于 oh-my-zsh。
答案2
您可能遇到的问题(您实际上没有提及)是,zsh
如果文件名通配模式与任何名称都不匹配,则默认情况下 shell 会发出错误:
$ downloadyoutube https://www.youtube.com/watch?v=_OBlgSz8sSM
zsh: no matches found: https://www.youtube.com/watch?v=_OBlgSz8sSM
这里的 URL 包含字符?
,它是一个通配符。这会提示 shell 使用 URL 作为模式执行文件名匹配。找不到匹配项,因此 shell 会抱怨,甚至不会尝试调用您的函数。
bash
如果failglob
设置了 shell 选项, shell中也会有类似的行为:
$ shopt -s failglob
$ downloadyoutube https://www.youtube.com/watch?v=_OBlgSz8sSM
bash: no match: https://www.youtube.com/watch?v=_OBlgSz8sSM
NOGLOB
您可以通过设置shell 选项来阻止 shell 使用 URL 作为通配模式setopt NOGLOB
。这将关闭当前 shell 会话中的通配符,直到您使用unsetopt NOGLOB
.
您还可以在函数调用前加上 前缀,这具有为单个命令noglob
设置 shell 选项的效果:NOGLOB
noglob downloadyoutube https://www.youtube.com/watch?v=_OBlgSz8sSM
然而,最明智的方法是在调用函数时使用单引号引用 URL。 URL 很可能包含其他shell 特有的字符不是&
例如,通配字符,它引入了后台作业。&
即使文件名通配关闭,如果不引用它,带有 in 的 URL将无法使用。
关闭通配符也不会禁用大括号扩展 ( {...}
) 或子 shell ( (...)
),这可能会在 URL 中意外发生。