Python: порождает процесс sudo (в новом терминале), дождитесь завершения - PullRequest
1 голос
/ 18 сентября 2011

Редактировать: мой окончательный код выглядит примерно так:

#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 завершается перед продолжением?

1 Ответ

3 голосов
/ 18 сентября 2011

Причина в том, что x-терминал-эмулятор запускает новый процесс и завершает работу, поэтому вы не можете знать, когда фактически выполненная команда завершается. Чтобы обойти это, решение было бы изменить вашу команду, чтобы добавить другую команду, которая уведомляет вас. Поскольку, очевидно, x-терминал-эмулятор выполняет только одну команду, мы можем использовать оболочку для их цепочки. Вероятно, не самый лучший способ сделать это, но один будет:

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")
...