отправка ввода текста на отдельный экран


44

Я пытаюсь запустить сервер Minecraft на моем сервере unRAID.

Сервер будет работать в оболочке, а затем сидеть и ждать ввода. Чтобы остановить его, мне нужно набрать «стоп» и нажать клавишу ввода, и тогда это спасет мир и изящно выйдет, и я вернусь в оболочку. Это все работает, если я запускаю его через telnetting в окно NAS, но я хочу запустить его прямо на коробке.

это то, что я ранее имел в качестве первой попытки:

#define USER_SCRIPT_LABEL Start Minecraft server
#define USER_SCRIPT_DESCR Start minecraft server. needs sde2 mounted first
cd /mnt/disk/sde2/MCunraid
screen -d -m -S minecraft /usr/lib/java/bin/java -Xincgc -Xmx1024M -jar CraftBukkit.jar

MCunraid - это папка, в которой у меня есть Craftbukkit.jar и все мировые файлы и т. Д. Если я наберу эту строку экрана напрямую, экран отсоединится и сервер запустится. Если я выполню эту строку из скрипта, то, похоже, не будет экрана

для остановки сервера мне нужно «напечатать» в STOP и затем нажать Enter. Мой подход был

screen -S minecraft -X stuff "stop $(echo -ne '\r')"

отправить на экран «майнкрафт» текстовый останов и возврат каретки. Но это не сработает, даже если я наберу его прямо в командной строке. Но если у меня «screen -r», я могу попасть на экран с запущенным сервером, а затем набрать «stop», и он отключится правильно.

Сервер работает нормально, если я подключаюсь по сети и делаю это вручную, просто нужно запустить его без подключения к удаленному компьютеру.


Это выглядит правильно . Каково полное содержание сценария и как вы его выполняете? Это производит какой-либо вывод? Как вы говорите, что screenне удалось запустить? Попробуйте добавить set -xв начало скрипта (сразу после #!строки) и сообщить результат трассировки при запуске скрипта.
Жиль "ТАК - перестань быть злым"

это полное содержание скрипта :) команда screen работает, если я набираю ее напрямую, поэтому я думаю, что моя главная проблема - это стоп-часть
richard plumb

Вы написали: «Если я выполню эту строку из скрипта, то, похоже, не настрою экран». Так стартовая часть работает или нет? Если это не так, см. Мой первый комментарий.
Жиль "ТАК - перестань быть злым"

Я пытаюсь запустить его как пользовательский скрипт unMENU. Если у меня есть пользовательский скрипт с этой точной экранной командой, ничего не происходит. Если я наберу команду screen в окне telnet, он запустит сервер на экране, как и следовало ожидать. Поэтому я думаю, что есть некоторая разница, которую я не понимаю в том, как обрабатываются пользовательские сценарии unMENU.
Ричард Пламб

Теперь мы куда-то добираемся. Пожалуйста, обновите ваш вопрос информацией о том, как вы используете unMENU. И попробуйте добавить две строки #!/bin/bashи set -xв верхней части сценария, и показать нам вывод трассировки из сценария. Возможно, вам придется заглянуть в документацию unMENU, чтобы узнать, куда идет этот вывод.
Жиль "ТАК - перестань быть злым"

Ответы:


40

Я могу решить хотя бы часть проблемы: почему эта stopчасть не работает. Экспериментально, когда вы запускаете сеанс Screen в отдельном режиме ( screen -d -m), окно не выбирается, поэтому вход, отправленный позже screen -X stuff, просто теряется. Вам нужно явно указать, что вы хотите отправить нажатия клавиш в окно 0 ( -p 0). В любом случае, это хорошая идея, если вы по какой-либо причине создадите другие окна в этом сеансе экрана.

screen -S minecraft -p 0 -X stuff "stop^M"

(Экран переводится ^Mв control-M, который является символом, отправленным Enterклавишей.)

Проблема с запуском сеанса из скрипта, вероятно, связана с unMENU.


1
красиво, прекрасно работает (по крайней мере, из командной строки, буду высовывать ребята из меню позже). Кажется, это бросило довольно много людей, и я впервые увидел конкретное решение. Я просто хочу , чтобы у меня было достаточно очков , чтобы проголосовать вас: D
Ричарду отвеса

Блин с ** т! Работает, даже экран уже прикреплен, без его подключения! Какой отличный способ отправлять команды в простые приложения из других приложений в системе. Благодарность! :)
Гжегож Вежовецкий

У меня никогда не было этой проблемы, возможно потому, что я всегда планировал иметь несколько (именованных) окон в своем сеансе экрана, и я всегда выбирал окно по имени.
Ekevoo

Вручную, для справки: -X Отправьте указанную команду в сеанс работающего экрана. Вы можете использовать опцию -S, чтобы указать сеанс экрана, если у вас запущено несколько сеансов экрана. Вы можете использовать опцию -d или -r, чтобы заставить экран искать только присоединенные или отключенные сеансы экрана. Обратите внимание, что эта команда не работает, если сеанс защищен паролем.
KrisWebDev

3
это не работает для меня. Я создал экран с, screen -d -m -S hiа затем запустил screen -S hi -p 0 -X stuff "cd <some_directory>^M"и ничего не получил в результате ... он просто отправляет "cd <some_directory> ^ M" в виде строки и не интерпретирует "^ M" как клавишу ввода ...
Tanner Strunk

23

Во-первых, заметка о простом вводе новых строк:

Просто напомнить, что $()конструкция удаляет символы новой строки из выходных данных команды, чтобы выходные строки могли использоваться в качестве аргументов для других программ. Это может вызвать неожиданное поведение. В этом случае я предполагаю, что вы специально пытаетесь отправить эквивалент Enterнажатия клавиши. Хотя возврат каретки, который вы отправляете \r, не будет чередоваться, есть несколько более простых способов ввода этого символа без необходимости в дополнительной команде.

  1. Вы можете поместить обычную новую строку в двойные кавычки

    screen -S minecraft -X stuff "stop
    "
    
  2. Или вы можете ввести символ в строке терминала, используя последовательность Ctrl+ v Enter. Это будет выглядеть примерно так же, как ^Mв терминале, но это специальный символ новой строки.

    screen -S minecraft -X stuff "stop^M"
    

Во-вторых, заметка о нестабильном поведении экрана. ( Объяснение и решение Жилем )

Экран имеет проблему с принятием ввода для сеанса экрана, который никогда не был присоединен. Если вы запустите это, он потерпит неудачу:

screen -d -m -S minecraft zsh
screen -S minecraft -X stuff "stop^M"
screen -r minecraft

Но если вы запустите это, это будет работать:

screen -d -m -S minecraft zsh
screen -r minecraft (then disconnect with Ctrl-a-d)
screen -S minecraft -X stuff "stop^M"
screen -r minecraft

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

GNU-Screen уже много лет является де-факто терминальным мультиплексором, но он давно перестал разрабатываться, и ошибки и причуды не исправляются. Tmux находится в активной разработке, включает в себя множество функций, которых экран не может касаться, и его поведение из коробки довольно интуитивно понятно. Кроме того, это лучше задокументировано. Вот как бы вы конвертировали свой код:

# Start new detached tmux session with a named window pane running the java app
tmux new-session -d -n minecraft /usr/lib/java/bin/java [args]

# Send it keys to stop the mincraft server
tmux send-keys -t minecraft "stop^M"

если я вручную переключаюсь с помощью screen -r, я вижу экран, и текст вообще не вводится. даже если возврат каретки не удался, я все равно должен был напечатать «стоп». Но ничего
Ричард Пламб

если у меня есть сценарий с screen -r в одной строке, а затем screen -X «stop ^ M», то он останавливает сервер, но также жалуется на «error uknown option r»
richard plumb

Я проверил здесь, создав сеанс экрана, затем используя команду выше, и она отлично работает. Вы можете подключиться к экранной сессии с помощью screen -d -RR minecraft?
Калеб

да, это соединяет меня с экраном. то же самое происходит с экраном -r .. если я попробую экран -S minecraft -X, "остановка ^ M", а затем вручную -r, на экране появится текст "стоп".
Ричард Пламб

Работает для меня. Возможно, у вас есть что-то напуганное .screenrcили у вас открыта целая куча сеансов экрана defunkt с таким именем, и вы отправляете данные не тому человеку? screen -list?
Калеб

4

Я извиняюсь за то, что выкопал этот старый пост, но это помогло бы мне в моих усилиях, если бы эта информация была доступна в то время, когда у меня была похожая проблема. Есть много вопросов о том, как отправлять экранные команды в bash-скрипте. Как и в случае с кошачьей шкурой, это может быть сделано, но мне нравится этот способ. При этом вы можете отправить любую команду или сказать что-нибудь, просто вызвав функцию say_this.

#!/bin/bash

say_this()
{
    screen -S minecraft -p 0 -X stuff "$1^M"
}

say_this "say Saving world"
say_this "save-off"
say_this "save-all"
...

Это с ssh!

#!/bin/bash

say_this()
{
    # Dont forget to set NAME or whatever
    ssh -p 8989 192.168.1.101 screen -S $NAME -p 0 -X stuff \"$1^M\"
}

say_this "say test"
say_this "say !@#$%^&*()<>?This string will work!"

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.