gửi văn bản đầu vào đến một màn hình tách rời


44

Tôi đang cố gắng chạy một máy chủ minecraft trên máy chủ unRAID của mình.

Máy chủ sẽ chạy trong shell, và sau đó ngồi đó chờ nhập liệu. Để ngăn chặn nó, tôi cần gõ 'stop' và nhấn enter, sau đó nó sẽ cứu thế giới và thoát ra một cách duyên dáng, và tôi trở lại vỏ bọc. Tất cả đều hoạt động nếu tôi chạy nó qua telnnet vào hộp NAS, nhưng tôi muốn chạy nó trực tiếp trên hộp.

đây là những gì trước đây tôi đã có như một nỗ lực đầu tiên:

#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

MCunston là thư mục nơi tôi có Craftbukkit.jar và tất cả các tệp trên thế giới, v.v ... Nếu tôi nhập trực tiếp dòng màn hình đó, màn hình sẽ thiết lập tách ra và máy chủ khởi chạy. Nếu tôi thực thi dòng đó từ trong tập lệnh, nó dường như không thiết lập màn hình

để dừng máy chủ, tôi cần 'gõ' trong STOP và sau đó nhấn enter. Cách tiếp cận của tôi là

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

để gửi tới màn hình 'minecraft' văn ​​bản dừng và trả lại xe ngựa. Nhưng nó không hoạt động, ngay cả khi tôi gõ nó trực tiếp vào dòng lệnh. Nhưng nếu tôi 'màn hình -r' tôi có thể vào màn hình với máy chủ đang chạy, sau đó nhập 'dừng' và nó tắt đúng cách.

Máy chủ chạy tốt nếu tôi telnet và thực hiện thủ công, chỉ cần chạy nó mà không cần kết nối từ máy tính từ xa.


Điều này có vẻ đúng . Nội dung đầy đủ của tập lệnh là gì và bạn đang chạy nó như thế nào? Nó có sản xuất bất kỳ đầu ra? Làm thế nào để bạn nói rằng screenthất bại để bắt đầu? Hãy thử thêm set -xở đầu tập lệnh (ngay sau #!dòng) và báo cáo đầu ra theo dõi khi bạn chạy tập lệnh.
Gilles 'SO- ngừng trở nên xấu xa'

đó là toàn bộ nội dung của tập lệnh :) lệnh màn hình hoạt động nếu tôi nhập trực tiếp, vì vậy tôi nghĩ vấn đề chính của tôi là phần dừng
richard plumb

Bạn đã viết ra Nếu tôi thực thi dòng đó từ trong tập lệnh, nó dường như không thiết lập một màn hình. Vì vậy, phần bắt đầu làm việc hay không? Nếu không, hãy xem bình luận đầu tiên của tôi.
Gilles 'SO- ngừng trở nên xấu xa'

Tôi đang cố chạy nó dưới dạng tập lệnh người dùng unMENU. Nếu tôi có tập lệnh người dùng với lệnh màn hình chính xác đó, không có gì xảy ra. Nếu tôi gõ lệnh màn hình vào cửa sổ telnet, nó sẽ khởi chạy máy chủ trong màn hình như bạn mong đợi. Vì vậy, tôi nghĩ rằng có một số khác biệt mà tôi không hiểu theo cách các tập lệnh người dùng unMENU được xử lý.
Richard plumb

Bây giờ chúng tôi đang nhận được ở đâu đó. Vui lòng cập nhật câu hỏi của bạn với thông tin về cách bạn đang sử dụng unMENU. Và hãy thử thêm hai dòng #!/bin/bashset -xở đầu tập lệnh, và hiển thị cho chúng tôi kết quả theo dõi từ tập lệnh. Bạn có thể cần xem tài liệu unMENU để tìm ra đầu ra đó đi đâu.
Gilles 'SO- ngừng trở nên xấu xa'

Câu trả lời:


40

Tôi có thể giải quyết ít nhất một phần của vấn đề: tại sao stopphần đó không hoạt động. Thực nghiệm, khi bạn bắt đầu một phiên Màn hình ở chế độ tách rời ( screen -d -m), không có cửa sổ nào được chọn, do đó, đầu vào được gửi sau đó screen -X stuffsẽ bị mất. Bạn cần xác định rõ ràng rằng bạn muốn gửi tổ hợp phím đến cửa sổ 0 ( -p 0). Dù sao đây cũng là một ý tưởng hay, trong trường hợp bạn tình cờ tạo các cửa sổ khác trong phiên Màn hình đó vì bất kỳ lý do gì.

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

(Dịch màn hình ^Msang control-M là ký tự được gửi bởi Enterkhóa.)

Vấn đề với việc bắt đầu phiên từ một tập lệnh có thể liên quan đến unMENU.


1
Đẹp, hoạt động tuyệt vời (ít nhất là từ dòng lệnh, sẽ chọc những kẻ không có kinh nghiệm sau này). Điều này dường như đã ném khá nhiều người và đây là lần đầu tiên tôi thấy một giải pháp cụ thể. Tôi chỉ ước mình có đủ điểm để bầu bạn: D
richard plumb

Chết tiệt! Nó hoạt động ngay cả màn hình đã được đính kèm, mà không cần gắn lại! Thật là một cách tuyệt vời để gửi lệnh đến các ứng dụng đơn giản từ các ứng dụng khác trong hệ thống. Cảm ơn! :)
Grzegorz Wierzowiecki

Tôi chưa bao giờ gặp vấn đề này, có lẽ vì tôi luôn có kế hoạch có một số cửa sổ (được đặt tên) trong phiên màn hình của mình và tôi luôn chọn cửa sổ theo tên.
Ekevoo

Hướng dẫn sử dụng, để tham khảo: -X Gửi lệnh được chỉ định đến phiên màn hình đang chạy. Bạn có thể sử dụng tùy chọn -S để chỉ định phiên màn hình nếu bạn có một vài phiên màn hình đang chạy. Bạn có thể sử dụng tùy chọn -d hoặc -r để báo cho màn hình chỉ nhìn cho các phiên màn hình được đính kèm hoặc tách rời. Lưu ý rằng lệnh này không hoạt động nếu phiên được bảo vệ bằng mật khẩu.
KrisWebDev

3
điều này không làm việc cho tôi. Tôi đã tạo một màn hình screen -d -m -S hivà sau đó chạy screen -S hi -p 0 -X stuff "cd <some_directory>^M"và không nhận được kết quả gì cả ... nó chỉ gửi "cd <some_directory> ^ M" dưới dạng một chuỗi và không hiểu "^ M" là khóa nhập ...
Tanner Strunk

23

Đầu tiên, một lưu ý về việc dễ dàng nhập các dòng mới:

Chỉ cần đề cập rằng $()cấu trúc sẽ loại bỏ các dòng mới từ đầu ra của lệnh để các dòng đầu ra có thể được sử dụng làm đối số cho các chương trình khác. Điều này có thể gây ra hành vi bất ngờ. Trong trường hợp này, tôi giả sử bạn đang cố gắng gửi tương đương với Entertổ hợp phím. Trong khi vận chuyển trở lại mà bạn đang gửi mà \rsẽ không bị sọc, có một số cách dễ dàng hơn để nhập ký tự đó mà không cần thêm lệnh.

  1. Bạn có thể đặt một dòng mới thường xuyên bên trong dấu ngoặc kép của bạn

    screen -S minecraft -X stuff "stop
    "
    
  2. Hoặc bạn có thể nhập ký tự trong một dòng thiết bị đầu cuối bằng cách sử dụng chuỗi Ctrl+ v Enter. Điều này sẽ trông giống như ^Mtrong thiết bị đầu cuối, nhưng nó là một nhân vật dòng mới đặc biệt.

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

Thứ hai, Một lưu ý về hành vi màn hình thất thường. ( Giải thích và giải pháp của Gilles )

Màn hình có vấn đề với việc chấp nhận đầu vào cho phiên màn hình chưa bao giờ được đính kèm. Nếu bạn chạy nó, nó sẽ thất bại:

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

Nhưng nếu bạn chạy nó, nó sẽ hoạt động:

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

Cuối cùng, bạn có thể sử dụng các hành vi tốt hơn nhiều tmuxthay vì screen.

GNU-Screen đã là một bộ ghép kênh đầu cuối thực tế trong nhiều năm, nhưng từ lâu nó đã không còn được phát triển và các lỗi và quirks không được sửa chữa. Tmux đang được phát triển tích cực, bao gồm nhiều tính năng mà màn hình không thể chạm vào và hành vi của nó ra khỏi hộp khá trực quan hơn. Ngoài ra, nó là tài liệu tốt hơn. Đây là cách bạn sẽ chuyển đổi mã của mình:

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

Nếu tôi tự chuyển qua sử dụng màn hình -r, tôi có thể thấy màn hình và không có văn bản nào được nhập. ngay cả khi việc quay trở lại xe ngựa không thành công, tôi vẫn nên gõ 'dừng lại'. Nhưng không có gì
Richard cày nát

nếu tôi có một tập lệnh với màn hình -r trên một dòng, và sau đó màn hình -X "dừng ^ M" thì nó sẽ dừng máy chủ, nhưng cũng phàn nàn với 'lỗi tùy chọn uknown r'
richard plumb

Tôi đã thử nghiệm ở đây bằng cách tạo phiên màn hình, sau đó sử dụng lệnh trên và nó hoạt động hoàn hảo. Bạn có thể kết nối với phiên màn hình của bạn bằng cách sử dụng screen -d -RR minecraft?
Caleb

vâng, điều đó kết nối tôi với màn hình. màn hình -r .. cũng vậy, nếu tôi thử màn hình -S minecraft -X thứ "dừng ^ M" rồi màn hình thủ công -r, có văn bản 'dừng' trong màn hình.
Richard plumb

Làm việc cho tôi. Có lẽ bạn có một cái gì đó thú vị trong bạn .screenrchoặc bạn có một loạt các phiên màn hình defunkt mở với tên đó và vì vậy bạn đang gửi dữ liệu đến sai? screen -list?
Caleb

4

Tôi xin lỗi vì đã đào bài cũ này, nhưng điều này sẽ giúp tôi trong nỗ lực của mình khi thông tin này có sẵn tại thời điểm tôi gặp vấn đề tương tự. Có rất nhiều câu hỏi về cách gửi lệnh màn hình trong tập lệnh bash. Như với việc lột da mèo có thể được thực hiện, nhưng tôi thích cách này. Với điều này, bạn có thể gửi bất kỳ lệnh nào hoặc nói bất cứ điều gì chỉ bằng cách gọi hàm 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"
...

Đây là với 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!"

Đẹp và
súc tích
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.