如何在 bash 中异步定义别名或变量?

如何在 bash 中异步定义别名或变量?

在 django 项目中,您会得到一个名为 的脚本manage.py,它有一堆子命令,例如runservermigrate等。您可以通过运行不带参数的脚本来获取所有子命令的列表。

我的计划是解析该输出,并使用它来支持之后的 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 的有用评论。

相关内容