Открыть новую консоль из скрипта, выполнить команду и стать интерактивным по завершении.

Вопрос или проблема

Я хочу, чтобы скрипт (который запускается при старте) открывал терминал konsole.
Когда он открывается, он должен выполнять некоторые постоянные действия (например, сменить директорию и загрузить bashrc) и запустить долгосрочную программу.
Если программа аварийно завершится или я остановлю ее с помощью <ctrl+c>, она должна начать принимать команды из стандартного ввода (например, ‘up-enter’ для попытки снова, как если бы она была интерактивной всё это время).

Я пробовал так много способов, чтобы это работало (в данный момент просто пытаюсь заставить его выполнить ls и вернуться в интерактивный режим по завершении);

konsole -e ls
konsole --hold ls
konsole -e /bin/bash -c ls
konsole --hold -e "/bin/bash -c ls"
konsole -e "/bin/bash -i -c ls"
konsole -e /bin/bash -i -c ls
konsole -e "echo ls > /tmp/konsolebash;/bin/bash -i --rcfile /tmp/konsolebash"

echo ls > /tmp/konsolebash
konsole -e "/bin/bash -i --rcfile /tmp/konsolebash"

Связано ли это с кавычками? Не следует ли их использовать, нужно ли экранировать что-то?
Должен ли я вообще пытаться выполнить bash?
Я исчерпываю идеи, но надеюсь, что это действительно достижимо (но надеюсь, это не что-то смущающе простое, что я пропустил).

Я оценю ответы, которые успешно используют другие эмуляторы терминала, если konsole в частности является проблемой (но поскольку вопрос касается именно konsole, я не думаю, что смогу дать вам желаемую галочку)

Благодаря комментариям @n.st я сделал эту однострочную команду:

konsole -e /bin/bash --rcfile <(echo "cd /;ls;echo hi | less")

Это просто более короткая версия без временных файлов, использующая подстановку процесса bash для следующего;

echo "cd /;ls;echo hi | less" > /tmp/konsolebash;konsole -e /bin/bash --rcfile /tmp/konsolebash

Которая выполнит некоторые команды, отобразит их, изменит окружение, запустит долгосрочную программу (less) и когда она завершится (:q), станет интерактивной.
Таким образом, замените cd /;ls;echo hi | less (демонстрацию) своим скриптом.

Нет истории, но по крайней мере теперь вы находитесь в правильной директории и имеете заданные переменные окружения, которые могли бы понадобиться.


В принципе, это то же самое, что и моя предыдущая попытка;

konsole -e "echo ls > /tmp/konsolebash;/bin/bash -i --rcfile /tmp/konsolebash"

за исключением того, что запись файла вне выполнения konsole, я убрал флаг -i, а параметры выполнения не находятся в одном блоке кавычек


К сожалению, ключ --rcfile не позволяет загружать ваш ~/.bashrc для этих команд, так что, если вам нужен был алиас или что-то подобное, вам придется сделать так;

cat ~/.bashrc > /tmp/konsolebash; echo "commands" >> /tmp/konsolebash;konsole -e /bin/bash --rcfile /tmp/konsolebash

Что просто копирует ваш bashrc, а затем добавляет ваши команды в конец.

Краткое и простое решение:

konsole -e '$SHELL -c "ls; $SHELL"' &

Это решение не имеет проблем с историей или загрузкой .bashrc.
Если ваша переменная окружения $SHELL не указывает на bash, вы можете указать ее вручную.

Это создает второй (bash) shell внутри того же окна терминала, поэтому некоторые вещи из первой команды могут не передаваться.

Ответ адаптирован из ответа askubuntu.

#!/bin/bash

#
# Если не запущен из konsole, создайте свой собственный
#
if [ ! -t 0 ]
then
    export konsole_instance_created=1
    konsole -e $0 $* &
    exit
fi

#
# Держите свой konsole открытым после завершения скрипта
#
if [ -n "$konsole_instance_created" ]
then
    unset konsole_instance_created
    trap $SHELL EXIT
fi

Этот код решает две задачи:

  • когда скрипт запускается из-за пределов konsole, он выполняется в новом экземпляре konsole, который не закрывается по завершении скрипта;
  • когда скрипт запускается внутри konsole, он ведет себя как обычно.

Этот код можно поместить в отдельный файл и включить с помощью . или source во все скрипты, которым нужно такое поведение.

Ответ или решение

Чтобы создать скрипт, который открывает новый терминал konsole, выполняет некоторые команды и остается интерактивным после завершения выполнения программы, вам нужно учесть несколько факторов. Ниже представлен пример такого скрипта.

Полное решение:

  1. Создайте новый скрипт (например, my_script.sh) с содержимым:
#!/bin/bash

# Функция для проверки, запущен ли скрипт в konsole
if [ ! -t 0 ]; then
    # Если нет, запускаем новый экземпляр konsole
    konsole -e "$0" &
    exit
fi

# Основные команды, которые вы хотите выполнить
cd /путь/к/вашей/директории || exit 1
source ~/.bashrc

# Выполнение длительной программы
программа_которая_долго_работает

# После завершения программы, переход в интерактивный режим
exec $SHELL
  1. Объяснение:

    • Проверка if [ ! -t 0 ]; then позволяет выявить, запущен ли скрипт в интерактивном терминале. Если нет, открывается новый konsole с выполнением того же самого скрипта.
    • cd позволяет установить необходимую директорию, source ~/.bashrc загружает ваши настройки оболочки.
    • Далее следует запуск вашей программы, которая может работать длительное время.
    • exec $SHELL в конце заменяет текущий процесс оболочки на интерактивную оболочку, позволяя вам продолжить ввод команд после завершения программы.
  2. Запуск:

    • Убедитесь, что ваш скрипт исполняемый. Для этого выполните:
      chmod +x my_script.sh
    • Запустите скрипт:
      ./my_script.sh

Примечания:

  • Вы можете заменить программа_которая_долго_работает на команду или скрипт, который хотите запустить.
  • Если ваш ~/.bashrc содержит алиасы или функции, которые вам нужны, данный скрипт гарантирует их доступность.
  • При нажатии Ctrl+C, программа будет прервана, возвращая вас в интерактивный режим без необходимости перезапуска терминала.

Такой подход позволяет вам организовать работу вашего скрипта в konsole, обеспечивая интерактивность и гибкость, о которых вы просили.

Оцените материал
Добавить комментарий

Капча загружается...