Тайм-аут coreutils в bash-скрипте не прозрачен для приложения - PullRequest
0 голосов
/ 24 августа 2018

У меня проблема с выполнением приложения через / usr / bin / timeout в bash-скрипте.В данном конкретном случае это простой скрипт фабрики Python (версия фабрики 1.14). Чтобы установить эту версию библиотеки фабрики, запустите: pip install "fabric <2". Нет новой копии с новой фабрикой 2.x. </p>

Сценарий оболочки, вызывающий проблему:

[root@testhost:~ ] $ cat testNOK.sh
#!/bin/bash
timeout 10 ./test.py
echo "RETCODE=$?"
[root@testhost:~ ] $ ./testNOK.sh
[localhost] run: echo Hello!
RETCODE=124
[root@testhost:~ ] $

Аналогичный сценарий (без тайм-аута) работает нормально

[root@testhost:~ ] $ cat testOK.sh
#!/bin/bash
./test.py
echo "RETCODE=$?"
[root@testhost:~ ] $ ./testOK.sh
[localhost] run: echo Hello!
[localhost] out: Hello!
[localhost] out:

RETCODE=0
[root@testhost:~ ] $

Ручное выполнение из командной строки bash с тайм-аутом работает:

[root@testhost:~ ] $ timeout 10 ./test.py && echo "RETCODE=$?"
[localhost] run: echo Hello!
[localhost] out: Hello!
[localhost] out:

RETCODE=0
[root@testhost:~ ] $

Python2.7 скрипт test.py

[root@testhost:~ ] $ cat test.py
#!/usr/bin/python
from fabric.api import run, settings

with settings(host_string='localhost', user='root', password='XXXXX'):
    run('echo Hello!')
[root@testhost:~ ] $

Я наблюдал одинаковое поведение в разных дистрибутивах Linux.

Теперь вопрос заключается в том, почему приложение, выполняемое по таймауту в скрипте bash, ведет себя по-разному.Кстати, а что было бы лучшим решением этой проблемы?

Ответы [ 2 ]

0 голосов
/ 25 августа 2018

Вам нужно вызвать timeout с опцией --foreground:

timeout --foreground ./test.py

Это требуется только в том случае, если команда timeout не выполняется из интерактивной оболочки (то есть, если она выполняется из файла сценария).

Цитирование со страницы информации timeout:

‘--foreground’
     Don’t create a separate background program group, so that the
     managed COMMAND can use the foreground TTY normally.  This is
     needed to support timing out commands not started directly from an
     interactive shell, in two situations.
       1. COMMAND is interactive and needs to read from the terminal for
          example
       2. the user wants to support sending signals directly to COMMAND
          from the terminal (like Ctrl-C for example)

Что в действительности происходит в этом случае, так это то, что матрица (или что-то вызывает) вызывает tcsetattr, чтобы отключить терминальное эхо. Я не знаю почему, но я предполагаю, что это как-то связано с процессом, используемым (не) для сбора пароля пользователя. (Я только что видел это сразу; я не пытался найти вызов.) Попытка изменить конфигурацию tty из фонового процесса приведет к блокировке процесса, пока он не восстановит контроль над tty, и это то, что происходит.

Этого не происходит, если timeout не используется, поскольку bash не создает фоновую группу программ. Я полагаю, что ткань 2 избегает вызова на tcsetattr.

Вероятно, вы также можете избежать этой проблемы, избегая аутентификации SSH на основе пароля, но я этого не пробовал.

Вы также можете избежать этой проблемы, перенаправив stdin на /dev/null (либо в команде timeout, либо в вызове сценария оболочки.) Если вам не нужно перенаправлять стандартный ввод в удаленную команду ( и вы, вероятно, не), это также может быть полезно.

0 голосов
/ 24 августа 2018

Вы можете использовать тайм-аут без использования bash. Просто используйте модель времени в python

import time

time.sleep(5)
#change the 5 by the seconds that you need to set a timeout
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...