Подтвердить что ты не робот

Что означает "bash: нет управления заданиями в этой оболочке"?

Я думаю, что это связано с родительским процессом, создающим новый подпроцесс и не имеющим tty. Может ли кто-нибудь объяснить детали под капотом? то есть соответствующей рабочей модели bash, создания процесса и т.д.

Это может быть очень широкая тема, поэтому ссылки на сообщения также очень ценятся. Я давно искал Googled, все результаты касаются очень конкретного случая, и никто не рассказывает об истории сцены. Чтобы предоставить больше контекста, ниже находится оболочка script, в результате получившая 'bash: отсутствие управления заданием в этой оболочке'.

#! /bin/bash

while [ 1 ]; do
    st=$(netstat -an |grep 7070 |grep LISTEN -o | uniq)
    if [ -z $st ]; then
        echo "need to start proxy @$(date)"
        bash -i -c "ssh -D 7070 -N [email protected] > /dev/null"
    else
        echo "proxy OK @$(date)"
    fi
    sleep 3
done

Эта строка:

bash -i -c "ssh -D 7070 -N [email protected] > /dev/null"

находится где "bash: управление заданиями в этой оболочке" не приходит.

4b9b3361

Ответ 1

Управление заданиями - это набор функций в оболочке и драйвер tty, которые позволяют пользователю управлять несколькими заданиями из одной интерактивной оболочки.

Задание - это одна команда или конвейер. Если вы запустите ls, это задание. Если вы запустите ls|more, это еще одно задание. Если запущенная вами команда запускает собственные подпроцессы, они также будут принадлежать к одной и той же задаче, если они не будут намеренно отсоединены.

Без управления заданиями вы можете поставить задание в фоновом режиме, добавив & в командную строку. И это обо всем, что у вас есть.

С помощью управления заданиями вы можете дополнительно:

  • Приостановить текущее задание переднего плана с помощью Ctrl Z
  • Возобновить приостановленное задание на переднем плане с помощью fg
  • Возобновить приостановленное задание в фоновом режиме с помощью bg
  • Приведите текущее фоновое задание на передний план с помощью fg

Оболочка поддерживает список заданий, которые вы можете увидеть, выполнив команду jobs. Каждому присваивается номер задания (отличный от PID процесса (процессов), которые составляют задание). Вы можете использовать номер задания с префиксом % в качестве аргумента fg или bg, чтобы выбрать задание на передний план или фон. Обозначение% jobnumber также приемлемо для команды built built kill. Это может быть удобно, поскольку номера заданий назначаются начиная с 1, поэтому они короче, чем PID.

Есть также ярлыки %+ для последнего задания переднего плана и %- для ранее заданного задания, поэтому вы можете быстро переключаться между двумя заданиями с помощью Ctrl Z, за которым следует fg %- ( приостановите текущую, возобновите вторую), не запомните цифры. Или вы можете использовать начало самой команды. Если вы приостановили команду ffmpeg, возобновить ее так же просто, как fg %ff (при условии, что никакие другие активные задания не начинаются с "ff" ). И как один последний ярлык, вам не нужно вводить fg. Просто введите %- в качестве команды, которая предваряет предыдущее задание.

"Но зачем нам это нужно?" Я слышу, как вы спрашиваете. "Я могу запустить другую оболочку, если хочу запустить другую команду". Правда, существует много способов многозадачности. В обычный день у меня есть оболочки входа, запущенные на tty1 через tty10 (да, их больше 6, вам просто нужно их активировать), один из которых будет запускать сеанс сеанса с 4 экранами в нем, другой может работать с ssh на котором есть еще один сеанс экрана, запущенный на удаленной машине, плюс мой X-сеанс с 3 или 4 xterms. И я все еще использую контроль над работой.

Если я нахожусь в середине vi или less или aptitude или любой другой интерактивной вещи, и мне нужно запустить несколько других быстрых команд, чтобы решить, как действовать, Ctrl Z, запустите команды, а fg станет естественным и быстрым. (Во многих случаях интерактивная программа имеет ! keybinding для запуска внешней команды для вас; я не думаю, что это так хорошо, потому что вы не получаете преимущества от истории вашей оболочки, редактора командной строки и системы завершения.) Я нахожу это печальным, когда вижу, что кто-то запускает вторичный xterm/screen/any, чтобы запустить одну команду, посмотрите на нее в течение двух секунд и затем выйдите.

Теперь об этом script. В общем, это, похоже, не написано грамотно. Линия, о которой идет речь:

bash -i -c "ssh -D 7070 -N [email protected] > /dev/null"

запутан. Я не могу понять, почему команда ssh передается в отдельную оболочку вместо того, чтобы просто выполняться прямо из основного script, не говоря уже о том, почему кто-то добавил к нему -i. Опция -i сообщает оболочке работать в интерактивном режиме, что активирует управление заданиями (между прочим). Но он фактически не используется в интерактивном режиме. Какова бы ни была цель за отдельной оболочкой и -i, предупреждение о контроле над работой было побочным эффектом. Я предполагаю, что это был хак, чтобы обойти некоторую нежелательную особенность ssh. Это то, что когда вы это делаете, вы должны прокомментировать это.

Ответ 2

Один из возможных вариантов не будет иметь доступ к tty.

Под капотом:

  • bash проверяет, является ли сеанс интерактивным, если нет - нет задания контроль.
  • Если установлено принудительное_интерактивное действие, тогда проверьте, что stderr прикрепленный к tty, пропускается, а bash проверяет снова, может ли он откройте /dev/tty для доступа на чтение и запись.
  • тогда он проверяет, используется ли новая линейная дисциплина, если нет, то также отключено управление заданиями.
  • Если (и только если), мы просто устанавливаем нашу группу процессов на наш pid, тем самым становясь лидером группы процессов, а терминал не входит в ту же группу процессов, что и наша (новая) группа процессов, затем устанавливаем группу терминальных процессов к нашей (новой) группе процессов. Если это не удается, установите нашу группу процессов обратно в исходное состояние (так что мы все еще можем читать с терминала) и отключить управление заданиями.
  • Если все вышеперечисленное не выполнено, вы увидите сообщение.

Я частично цитировал комментарии из bash исходного кода.

[править]

В соответствии с дополнительным запросом автора вопроса:

http://tiswww.case.edu/php/chet/bash/bashtop.html Здесь вы можете найти bash.

Если вы можете прочитать код C, получите исходный tarball, внутри него вы найдете job.c - это объяснит вам больше "под капотом".:)

Ответ 3

У меня возникла проблема с моей встроенной системой, и я избавился от ошибки "отсутствия контроля работы", запустив процесс getty с помощью "setsid", который в соответствии с его man-страницей запускает процесс с новым идентификатором сеанса.

С уважением, Хайко

Ответ 4

Вам может потребоваться включить управление заданиями:

#! /bin/bash   
set -m