在 django 项目中,您会得到一个名为 的脚本manage.py
,它有一堆子命令,例如runserver
、migrate
等。您可以通过运行不带参数的脚本来获取所有子命令的列表。
我的计划是解析该输出,并使用它来支持之后的 TAB 补全. manage.py
,并设置别名,这样我就可以直接输入migr[TAB]
而不是输入./manage.py migrate
。
我的问题是,因为它是 Python,和它需要加载所有 django 机制才能显示子命令,对于一个非常小的项目,我每次都要等待大约半秒钟。项目越大,花费的时间越长。
我的想法是在后台任务中运行脚本的询问、别名的定义和自动完成的设置
(for subcommand in parse_manage_py; do alias $subcommand='./manage.py $subcommand'; done) &
但这并没有在父 shell 中设置任何变量。我花了export
一段时间才弄清楚应该“向下”导出而不是“向上”导出。
答案1
一种(不太优雅的)方法可能是将异步进程(执行缓慢的工作)的输出重定向到文件,并仅在第一次需要时使用该文件的内容。您可以同时做一些事情。例如:
# placing everything into a function only because it easier to test
function func {
# Test (I think that "runserver" is one of the alias you should get)
echo -n "start: "
alias -p|grep -q runserver && \
echo \"runserver\" is defined || \
echo \"runserver\" is NOT defined
# prepare the aliases in background
f=$(mktemp)
( python ./manage.py | \
sed -n 's/^ \(.*\)/alias \1=".\/manage.py \1"/p'
sleep 2 # simulate slow process
) >$f &
slow_process_id=$!
# here you can do things...
echo "I'm doing thing..."
sleep 1
echo "...finished my things. Waiting for the aliases"
# but if you need the aliases you must check that they are ready
wait $slow_process_id
source $f
rm -f $f
echo "Aliases ready :-)"
# Test again
echo -n "end: "
alias -p|grep -q runserver && \
echo \"runserver\" is defined || \
echo \"runserver\" is NOT defined
}
另请参阅coproc ... command ...
,但我认为当命令终止时它的文件句柄就会消失。
我也尝试过两次错误的方法:首先,我尝试让我的脚本source
从子进程中定义一些别名,但这些别名当然不会对调用 shell 起作用。这里的问题是&
生成了一个子 shell。
然后我尝试使用间接引用。这里的问题是“间接”变量并不特殊,并且它们与调用 shell 是分开的。
感谢 G-Man 的有用评论。