问题描述
我有一个小功能可以让我激活我的 python 虚拟环境,对于不同的存储库,它有时是隐藏的 (.venv
),有时不是 (venv
)。我无法抑制 stderr。
这是我的小函数(它存在于~/.zshrc
中)
function venv {
source `ls -a $PWD/*/bin/activate` > /dev/null
if [[ $? -ne 0 ]]
then
source `ls -a $PWD/.*/bin/activate`
fi
}
只存在 $PWD/*/bin/activate
或 $PWD/.*/bin/activate
之一,我想忽略不存在的那个,没有错误。
问题是这一行
ls -a $PWD/*/bin/activate 2>&1 /dev/null
给出终端输出
zsh: no matches found: /home/jokea/code/flora/*/bin/activate
我的理解是 2>&1 /dev/null
应该同时抑制 stderr 和 stdout。那么为什么它不起作用?
我已经尝试了我能找到的所有其他变体(>
、>>
、&>
、>&
等),但它仍然打印到终端。如何使函数的所有输出静音?
解决方法
这里有两件事让我烦恼:
ls -a $PWD/*/bin/activate 2>&1 /dev/null
重定向的顺序不正确(您重定向 std 输出中的错误)并且 /dev/null
没有以流重定向为前缀。
您应该首先将 std 输出重定向到 /dev/null
,然后将 std 错误重定向到与 std 输出相同的流(即 /dev/null
):
ls -a $PWD/*/bin/activate > /dev/null 2>&1
,
使用其他答案并没有让我完全明白,但根据 davidxxx 和 rowboat 的建议(感谢这些),我把这个:
function venv {
setopt +o nomatch
ls -a $PWD/.*/bin/activate > /dev/null 2>&1
if [[ $? -eq 0 ]]
then
source `ls -a $PWD/.*/bin/activate` > /dev/null 2>&1
else
ls -a $PWD/*/bin/activate > /dev/null 2>&1
if [[ $? -eq 0 ]]
then
source `ls -a $PWD/*/bin/activate` > /dev/null 2>&1
else
echo "There's no Virtual Environment in $PWD"
fi
fi
}
诚然,这有点垃圾,但它有效。我现在可以毫无错误地设置虚拟环境。
,在我看来,在 zsh 通配符 *
扩展中可能并不总是考虑 stderr 重定向。
我常用的更清洁的解决方案是这样的:
find . -maxdepth 2 -name activate -type f -print |
grep /bin/ |
head -1 |
while read script
do source "$script"
done