编辑:我的最终代码是这样的:
#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进程在继续之前完成?
答案 0 :(得分: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")