Я хотел бы запустить что-то вроде этого:
bash -c "some_program with its arguments"
но иметь интерактивный bash продолжать работать после some_program
концов.
Я уверен, что -c
это не очень хорошо, как man bash
Сейс:
Интерактивная оболочка запускается без аргументов без опций и без опции -c
Так как это сделать?
Основная цель описана здесь
НОТА
- Мне нужно прекратить
some_program
время от времени - Я не хочу ставить это на задний план
- Я хочу остаться на
bash
то, чтобы сделать что-то еще - Я хочу иметь возможность снова запустить программу
pty.
fg
Ответы:
Это лучше сделать из скрипта, хотя с помощью
exec $0.
Или, если один из этих файловых дескрипторов направляет на терминальное устройство, которое в данный момент не используется, это поможет - вы должны помнить, что другие процессы тоже хотят проверить этот терминал.И, кстати, если ваша цель, как я полагаю, заключается в том, чтобы сохранить среду сценария после ее выполнения, вам, вероятно, будет гораздо лучше справляться с:
Оболочки
.dot
иbash's source
не одно и то же - оболочка -.dot
это POSIX, заданная как специальная встроенная оболочка, и поэтому она настолько близка к гарантированности, насколько вы можете получить, хотя это ни в коем случае не является гарантией того, что она будет там ...Хотя вышесказанное должно делать, как вы ожидаете, с небольшой проблемой. Например, вы можете:
Оболочка запустит ваш скрипт и вернет вас к интерактивному приглашению - при условии, что вы исключите
exit
оболочку из вашего скрипта, то есть не создадите фоновый режим для вашего процесса - который свяжет ваш ввод / вывод/dev/null.
DEMO:
МНОГИЕ
JOBS
По моему мнению, вам следует немного ближе познакомиться со встроенными в оболочку параметрами управления задачами. @Kiwy и @jillagre уже упоминали об этом в своих ответах, но это может потребовать дополнительных подробностей. И я уже говорил один POSIX-указанную специальную оболочку встроенный, но
set, jobs, fg,
иbg
еще несколько, и, как показывает другой ответtrap
иkill
еще два по- прежнему.Если вы еще не получаете мгновенные уведомления о состоянии одновременно запущенных фоновых процессов, это потому, что ваши текущие параметры оболочки установлены на POSIX-значение по умолчанию
-m
, но вы можете получить их асинхронно с помощьюset -b
:Очень фундаментальной особенностью Unix-систем является их метод обработки
signals
. Однажды я прочитал поучительную статью на эту тему, которая сравнивает этот процесс с описанием планеты Дугласом Адамсом. Что:Это относится к
kill signals
.По крайней мере для меня приведенная цитата ответила на множество вопросов. Например, я всегда считал это очень странным и совсем не интуитивным, что, если я хотел контролировать
dd
процесс, я должен былkill
это делать . После прочтения это имело смысл.Я бы сказал, что большинство из них не пытаются адаптироваться по уважительной причине - это может быть гораздо большим раздражением, чем благом иметь кучу процессов, спамующих ваш терминал любой информацией, которую их разработчики посчитали важной для вас. ,
В зависимости от конфигурации вашего терминала (которую вы можете проверить
stty -a
) ,CTRL+Z
скорее всего, он настроен на перенаправлениеSIGTSTP
текущего лидера группы процессов переднего плана, который, вероятно, является вашей оболочкой, и который также должен быть настроен по умолчанию наtrap
этот сигнал и приостановить вашу последнюю команду. Опять же, как показывают ответы @jillagre и @Kiwy вместе, вы не сможете помешать вам адаптировать эту функциональность к вашим целям по вашему усмотрению.SCREEN JOBS
Поэтому, чтобы воспользоваться этими функциями, вы должны сначала понять их и настроить их обработку в соответствии с вашими потребностями. Например, я только что нашел этот screenrc на Github, который включает
screen
привязки клавиш дляSIGTSTP
:Это упростит приостановку процесса, выполняющегося как дочерний
screen
процесс, или самогоscreen
дочернего процесса, как вы пожелаете.И сразу после этого:
ИЛИ:
Будет ли на переднем плане или фона процесс, как вы предпочитаете.
jobs
Встроенный может предоставить вам список из них в любой момент. Добавление-l
операнда будет включать в себя детали pid.источник
Вот более короткое решение, которое выполняет то, что вы хотите, но может не иметь смысла, если вы не понимаете проблему и то, как работает bash:
Это запустит оболочку bash, запустится
some_program
, и послеsome_program
выхода вы перейдете в оболочку bash.В основном то, что мы делаем, - это добавляем bash в строку STDIN. Эта строка
some_program with its arguments; exec </dev/tty
. Это говорит bashsome_program
сначала запустить , а затем запуститьexec </dev/tty
после. Поэтому вместо того, чтобы продолжать читать команды из строки, которую мы передаем, bash начнет чтение с/dev/tty
.Это
-i
происходит потому, что когда запускается bash, он проверяет, является ли STDIN tty, а при запуске - нет. Но позже это произойдет, поэтому мы переходим в интерактивный режим.Другое решение
Еще одна идея, которую я подумал об этом, была бы очень переносимой - добавить следующее в самый конец вашего
~/.bashrc
файла.Затем, если вы хотите сначала запустить оболочку с помощью команды, просто выполните:
Объяснение:
Большая часть этого должна быть очевидна, но резонанс для изменения имени переменной таков, что мы можем локализовать переменную. Поскольку
$START_COMMAND
это экспортируемая переменная, она будет унаследована любыми дочерними элементами оболочки, и, если другая дочерняя оболочка bash является одним из этих дочерних элементов, она снова запустит команду. Поэтому мы присваиваем значение новой неэкспортированной переменной ($start_command
) и удаляем старую.источник
<<<
это не POSIX, но вы могли быecho "string here" | bash -i
вместо этого. Тогда есть то,/dev/tty
что является вещью Linux. Но вы могли бы дублировать FD перед запуском bash, а затем снова открыть STDIN, что похоже на то, что вы делаете, но я решил оставить все как есть./dev/tty
это не вещь Linux, но определенно POSIX.Это должно сделать трюк:
Редактировать:
Вот новая попытка после вашего обновления:
Используйте ControlC, вам будет представлено это маленькое меню:
Это тот случай.
Выберите "bash" выбор
Выберите «перезагрузить» выбор
источник
CTRL+C
является лишь побочным эффектом конфигурации вашего терминала по умолчанию, чтобы интерпретировать его какSIGINT
. Вы можете изменить это, как вы будете сstty
.SIGINT
находитсяtrapped
выше2
.Вы можете сделать это, передав свой скрипт как файл инициализации:
Или вы можете передать его в командной строке:
Обратите внимание, что это
--init-file
было предназначено для чтения файлов инициализации всей системы, например,/etc/bash.bashrc
так что вы можете захотетьsource
«это» в вашем скриптеисточник
Я не вижу смысла делать это, так как вы уже возвращаетесь в оболочку после запуска этой программы. Тем не менее, вы могли бы к этому:
Это запустит интерактивный bash после запуска программы.
источник
Вы можете поместить команду в фоновом режиме, чтобы сохранить текущий текущий bash:
Чтобы вернуться к работе, вы можете использовать
fg
команду и^+z
снова поместить ее в фоновый режим.источник
bash
или нет, вы используете очень инопланетную оболочку для меня, если она не справляется с фоновым процессом. И я согласен с Киви - эта информация послужила бы вам лучше, если бы она была в вашем вопросе.Вы можете использовать экран для запуска команды. Затем вы можете присоединиться к сеансу после завершения команды.
Кроме того, просто запустите команду в фоновом режиме
some_program with its arguments&
. Это даст вам возможность повторно выполнить команду и получить статус команды после ее завершения.источник
screen
но перенести его в фоновый режим для меня бесполезно - иногда мне нужно завершить программу, сделать что-то еще и запустить ее снова. И главная цель - сделать это быстро.kill %
илиkill %1
.