入力された画面にテキスト入力を送信する


44

unRAIDサーバーでMinecraftサーバーを実行しようとしています。

サーバーはシェルで実行され、そこに座って入力を待ちます。停止するには、「stop」と入力してEnterキーを押す必要があります。そうすると、世界が保存されて正常に終了し、シェルに戻ります。NASボックスにtelnetを介して実行する場合はすべて動作しますが、ボックスで直接実行する必要があります。

これは私が以前に最初の試みとして持っていたものです:

#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')"

テキストストップとキャリッジリターンを画面「minecraft」に送信します。しかし、コマンドラインに直接入力しても、機能しません。しかし、「screen -r」を実行すると、サーバーが稼働している状態で画面に移動できます。「stop」と入力すると、適切にシャットダウンします。

サーバーは、telnetで接続して手動で実行した場合は正常に動作します。リモートコンピューターから接続せずに実行するだけです。


これは正しく見えます。スクリプトの完全な内容は何ですか、それをどのように実行していますか?出力は生成されますか?screen起動に失敗したことをどのように確認しますか?set -xスクリプトの先頭(#!行の直後)に追加してみて、スクリプトの実行時にトレース出力を報告してください。
ジル 'SO-悪であるのをやめる'

それは、スクリプトの完全な内容です:)私は直接にそれを入力すると、画面のコマンドは動作しますが、私は私の主な問題は、ストップ部分だと思うので
リチャード下げ振り

「スクリプト内からその行を実行すると、画面が設定されないようです」と書きました。それでは、開始部分は機能するのでしょうか?そうでない場合は、私の最初のコメントを参照してください。
ジル 'SO-悪であるのをやめる'

unMENUユーザースクリプトとして実行しようとしています。その正確なスクリーンコマンドを使用したユーザースクリプトがある場合、何も起こりません。telnetウィンドウにscreenコマンドを入力すると、期待どおりの画面でサーバーが起動します。そのため、unMENUユーザースクリプトの処理方法に理解できない違いがあると思います。
リチャード配管

今、私たちはどこかに到達しています。unMENUの使用方法に関する情報で質問を更新してください。そして、2行を追加してみない#!/bin/bashset -x、スクリプトの先頭に、そして私たちのスクリプトからのトレース出力を示しています。その出力がどこにあるかを知るために、unMENUドキュメントを見る必要があるかもしれません。
ジル 'SO-悪であるのをやめる'

回答:


40

私は問題の少なくとも一部を解決することができます:なぜ機能してstopいないのか。実験的に、分離モード(screen -d -m)でScreenセッションを開始すると、ウィンドウは選択されないため、後で送信された入力screen -X stuffは失われます。キーストロークをウィンドウ0(-p 0)に送信することを明示的に指定する必要があります。何らかの理由でそのScreenセッションで他のウィンドウを作成した場合に備えて、とにかくこれは良い考えです。

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

(画面^Mは、Enterキーによって送信された文字であるcontrol-Mに変換されます。)

スクリプトからセッションを開始する際の問題は、おそらくunMENUに関連しています。


1
美しく、素晴らしい作品です(少なくともコマンドラインからは、後でメニューを外す人を突くでしょう)。これはかなりの数の人を投げたようで、具体的な解決策を見たのは初めてです。D:私はちょうど私があなたを投票するのに十分なポイントがあればいいのに
リチャード下げ振り

くそっ!画面が既に接続されていても、再接続せずに動作します!システム内の他のアプリからシンプルなアプリにコマンドを送信する素晴らしい方法は何ですか。ありがとう!:)
Grzegorz Wierzowiecki

おそらく、スクリーンセッションに複数の(名前の付いた)ウィンドウを表示することを常に計画し、常に名前でウィンドウを選択したため、この問題は発生しませんでした。
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」をEnterキーとして解釈しません...
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を使用して手動で切り替えると、画面が表示され、テキストがまったく入力されません。キャリッジリターンが失敗した場合でも、私はまだ「停止」で入力する必要があります。しかし、何もありません。
リチャードコロッ

1行にscreen -rを含むスクリプトがあり、screen -Xに "stop ^ M"を指定すると、サーバーは停止しますが、 'error uknown option r'
richard plumb

ここでは、スクリーンセッションを作成し、上記のコマンドを使用してテストしましたが、完全に機能します。を使用してスクリーンセッションに接続できますscreen -d -RR minecraftか?
カレブ

はい、それは私を画面に接続します。screen -r ..がハングアップします。screen-S minecraft -Xの「stop ^ M」を試してから、手動でscreen -rを実行すると、画面に「stop」テキストが表示されます。
リチャード

私のために働く。たぶん、あなたは自分の中でファンキーな何かを持っているか.screenrc、その名前でたくさんの不要なスクリーンセッションを開いているので、間違ったものにデータを送信していますか?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!"

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.