Почему некоторые команды 'подвешивают' терминал, пока они не закончили?

Вдохновленный Вашим выражением, я могу придумать более короткое, с помощью egrep:

egrep -v '(s.*s|p.*p|i.*i|n.*n|e.*e)' FILE

который эквивалентен

sed /s.*s/d;/p.*p/d;/i.*i/d;/n.*n/d;/e.*e/d; FILE

И это - то, как произвести sed-команду из входа автоматически:

#!/bin/bash
word=$1
file=$2
expr=$(for c in $(echo $word | sed 's/./& /g'); do echo -n "/"$c".*"$c"/d;"; done);
sed $expr $file 

Я попробовал аналогичный подход grep, но не мог убедить оболочку брать grep-шаблон от переменной, но если я повторил его и вставил результат с вырезанным и вставленным, команда работала:

expr="'("$(for c in $(echo $wort | sed 's/./& /g'); do echo -n $c".*"$c"|"; done)

egrep -v ${expr/%|/)\'} FILE
# doesn't work, filters nothing, whole file is printed
# check:    
echo egrep -v $(echo $exp) FILE 
egrep -v '(s.*s|p.*p|i.*i|n.*n|e.*e)' FILE
# manually: 
egrep -v '(s.*s|p.*p|i.*i|n.*n|e.*e)' FILE
spine
spin
pine

Возможно, я совершил ошибку, возможно, я делаю ошибку с переменным расширением.

23
22.02.2015, 07:27
4 ответа

По умолчанию терминал запустит программу на переднем плане, таким образом, Вы не закончите назад в оболочке, пока программа не закончилась. Это полезно для программ, которые читают из stdin и/или пишут в stdout - Вы обычно не хотите многих из них работающий сразу. Если Вы хотите, чтобы программа работала в фоновом режиме, можно запустить ее как это:

$ lxpanel &

Или если это уже работает, можно приостановить его с Ctrl+Z и затем работать bg перемещать его в фон. Так или иначе Вы закончите с новым приглашением оболочки, но программа все еще работает, и ее вывод появится в терминале (таким образом, она сможет внезапно обнаружиться, в то время как Вы посреди ввода),

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

28
27.01.2020, 19:42
  • 1
    Таким образом, что на самом деле делает система, когда Вы запускаете программу через окно 'выполнения' путем нажатия Alt + f2? (по крайней мере, на гноме и openbox, alt+f2 делает это). Я спрашиваю, потому что, как только Вы вводите команду, программа запускается, и поле уходит. это просто добавляет a и к нему? –  sqram 26.12.2011, 12:05
  • 2
    @lyrae: по умолчанию оболочка ожидает программы для завершения прежде, чем продолжить сессию оболочки, она не "зависает", по любому определению "зависают"; alt+f2 не ожидает программы. Причина, которую оболочка ожидает программы для завершения, состоит в том, потому что оболочка может перенаправить то, что пользователь, введенный в оболочку к стандартному входу программы и/или, отображают стандартный вывод программы. Так как alt+f2, прежде всего, используется для запуска программы GUI, alt+f2 не обеспечивают возможность использования стандартного ввода/вывода и таким образом, это не должно ожидать. –  Lie Ryan 26.12.2011, 12:20
  • 3
    @lyrae: alt+f2 не делает ничего специального для запуска программы в фоне; это - оболочка, это делает что-то специальное, добавление '&' является функциональностью оболочки. При запуске команды без '& ', оболочка перенаправляет стандартный вход программы к своему собственному стандартному входу и стандартный вывод программы к его собственному стандартному выводу (немного изобретенный, так как оболочка также предоставляет многие другие услуги, такие как прерывание Ctrl-C, для отправки команды сигнала SIGINT в приоритетную программу). '&' говорит оболочке не делать их и просто запускать программу (также изобретенный). –  Lie Ryan 26.12.2011, 12:31
  • 4
    @LieRyan часть из того, что Вы говорите, что оболочка делает, на самом деле обрабатывается терминальным драйвером ядра, и "с и", является обычно более "особенным", чем "без и", кроме которого вызовы оболочки ожидают () [или waitpid или эквивалентный], который не сделан alt-f2. –  Random832 26.12.2011, 20:12

При запуске программы в терминале терминал "зависнет", пока программа не останавливается. Путем нажатия Ctrl+c Вы закрываете свою программу и таким образом возвращаетесь к подсказке. Вы будете видеть это со всеми приложениями для GUI, попробовать Firefox, например.

При использовании некоторого другого метода, такого как Alt+F2 или нажимающий через меню программа запущена в фоновом режиме, таким образом, ничего странного не происходит (и нет никакой командной строки так или иначе).

Если Вы все еще хотите запустить приложения для GUI от терминала, добавить & в конце Вашей команды, как так

lxpanel &

Это говорит терминалу работать lxpanel в фоновом режиме и дайте Вам другую подсказку сразу.

7
27.01.2020, 19:42

Программы, запущенные через оболочку, выполненную на переднем плане той оболочки по умолчанию. Это заставляет оболочку приостанавливать операцию и прямой stdin/stdout/sterr от терминала до программы. Программы, запущенные через настольную среду, разветвлены, который заставляет их работать независимый от программы, которая выполнила их. Это может быть моделировано в большинстве оболочек путем добавления a & к команде, хотя это все еще подключит станд.* к терминалу (хотя чтение из stdin на фоновой программе имеет дальнейшие сложности).

3
27.01.2020, 19:42

И фоны хорошо за исключением программ, которые возвращаются, требуя консольного взаимодействия позже (например, "способное обновление-y и", который в конечном счете вводит состояние ОСТАНОВКИ, так как оно желает предложить пользователю "действительно действительно сила?" вопрос намного позже...., когда никто не смотрит больше).

Чтобы заткнуть ту дыру и сообщить процессу, терминал никогда будет действительно никогда не становиться доступным ему, я добавляю <&-к некоторым моим командам, полностью отсоединяя их от активного терминала, говоря им, STDIN больше не возможен. Удостоверьтесь, что/bin/bash является Вашей оболочкой при использовании этого все же. Сценарий продолжит регистрировать любые ошибки, связанные ни с каким псевдотерминалом, являющимся доступным, на котором можно бросить любую подсказку.

Например:

`./runme.sh &> runme.log <&- & disown`

мой окончательный способ разъединить с текущим терминальным сеансом. И STDOUT и STDERR зарегистрированы к runme.log, не будет иметь значения, если Ваша консоль или окружит оконечный раньше или если Вы, logout/su в другую учетную запись (никакой терминальный мусор от runme), и благодаря отрицают даже родительско-дочерние отношения PID, удалены.

ОБНОВЛЕНИЕ: даже с этим я испытал затруднения из-за семафора, связывающего его с названием исходного родителя, поэтому теперь я рекомендую вместо этого:

at now <<< "(cmd1; cmd2; etc.) &> logfile.log"

Конечно, удалите и>, если Вы хотите быть отправленными по электронной почте вывод от КРОНА или перенаправить все это к/dev/null вместо файла.

2
27.01.2020, 19:42
  • 1
    немного менее замысловатый способ достигнуть этого, которое я начал использовать, at now <<< "(cmd1; cmd2; etc.) &> logfile.log" –  Marcos 31.01.2012, 13:11

Теги

Похожие вопросы