1

编辑:我的最终代码是这样的:

#WARNING: all " in command need to be escaped: \\"
def spawnInNewTerminal(command):
    #creates lock file
    lock = open(lockPath, 'w')
    lock.write("Currently performing task in separate terminal.")
    lock.close()

    #adds line to command to remove lock file
    command += ";rm " + lockPath

    #executes the command in a new terminal
    process = subprocess.Popen (
        ['x-terminal-emulator', '-e',  'sh -c "{0}"'.format(command) ]
        , stdout=subprocess.PIPE )
    process.wait()

    #doesn't let us proceed until the lock file has been removed by the bash command
    while os.path.exists(lockPath):
        time.sleep(0.1)

原始问题:

我正在编写一个简单的包装器,在最终运行 LuaLaTeX 之前“即时”安装任何丢失的包。它主要工作,但接近尾声,我必须运行命令

sudo tlmgr install [string of packages]

此外,由于不能保证 LaTeX 编辑器允许用户输入,我必须调用一个新终端来执行此操作,以便他们输入他们的 sudo 密码。

我基本上已经弄清楚了:要么

process = subprocess.Popen(
    shlex.split('''x-terminal-emulator -t \'Installing new packages\' -e \'sudo tlmgr install ''' + packagesString + '''\''''), stdout=subprocess.PIPE)
retcode = process.wait()

或者

os.system('''x-terminal-emulator -t \'Installing new packages\' -e \'sudo tlmgr install ''' + packagesString + '''\'''')

唯一的问题是,这条线不会等到生成的终端进程完成。事实上,它会立即继续到下一行(运行实际的 LuaLaTeX),甚至在用户输入密码或下载包之前!

据我了解,这是因为 sudo 子进程立即完成。有没有办法确保 tlmgr 进程在继续之前完成?

4

1 回答 1

3

原因是 x-terminal-emulator 产生了一个新进程并退出,所以你无法知道执行的命令何时真正完成。要解决这个问题,一个解决方案是修改您的命令以添加另一个通知您的命令。由于显然 x-terminal-emulator 只执行一个命令,我们可以使用 shell 链接它们。可能不是最好的方法,但一种方法是:

os.system('x-terminal-emulator -t "Installing new packages" -e "sh -c \\"sudo tlmgr install %s; touch /tmp/install_completed\\""' % packagesString)
while not os.path.exists("/tmp/install_completed"):
    time.sleep(0.1)
os.remove("/tmp/install_completed")
于 2011-09-17T22:59:30.367 回答