Ngăn màn hình GNU kết thúc phiên sau khi tập lệnh thực thi kết thúc


34

Tôi đang cố gắng buộc màn hình GNU tạo một thiết bị đầu cuối "ảo", mà không gắn vào nó, thực thi tập lệnh bên trong và KHÔNG chấm dứt phiên sau khi tập lệnh kết thúc.

Tôi đã thử nhiều kết hợp, bao gồm:

screen -dmS udplistener /share/Sys/autorun/start_udp_listeners.sh

hoặc là

screen -S udplistener -X /share/Sys/autorun/start_udp_listeners.sh

và không ai trong số họ làm việc. Tôi nhận được phiên mà không có tập lệnh thực thi, tập lệnh thực thi, nhưng phiên bị chấm dứt khi nó kết thúc hoặc tôi gặp lỗi "Không tìm thấy phiên màn hình".

Những gì tôi về cơ bản đang cố gắng làm là chạy trình nghe UDP, được viết bằng PHP và làm cho nó hoạt động theo vòng lặp infinte (không ngắt nghe). Có - Tôi có thể chạy tập lệnh PHP &ở cuối, buộc PHP CLI chạy dưới dạng daemon. Vấn đề là, tôi đang sử dụng một mẩu rác được gọi là máy chủ (QNAP - không bao giờ, không bao giờ mua rác này!) Mà dường như đang bỏ qua điều này. Ngay khi tôi đăng xuất phiên SSH, tập lệnh dừng lại.

Vì vậy, screendường như là lựa chọn duy nhất. Nhưng tôi không thể hiểu, tại sao nó kết thúc phiên sau khi lệnh thực thi hoặc tập lệnh kết thúc?

EDIT : Tôi cũng đã thử ví dụ tìm thấy trên Internet:

screen -dmS name
screen -S name -p windowname -X stuff 'mc
'

Không thiếu! Sau khi đính kèm với nó ( screen -R name) tôi thấy rằng Chỉ huy nửa đêm đã bị xử tử. Mặc dù ví dụ tác giả đã nói, nó sẽ được.


Cách bạn đang gọi screen, bạn chỉ tạo một cửa sổ để chạy một lệnh duy nhất. Khi lệnh thoát, cửa sổ đóng lại và screenkhông còn gì để làm, vì vậy nó thoát.
jw013

Vậy ... có cách nào để mở hai cửa sổ (chỉ sử dụng dòng lệnh, không kết hợp bàn phím), một để thực thi tập lệnh và thứ hai để ngăn không screenđóng? BTW: Tôi vẫn không hiểu ý tưởng đằng sau! Nếu tôi gọi screen -dmS name, tôi tạo một cửa sổ tách ra, cũng không còn gì để làm. Nhưng nó không tự động đóng! Nhưng khi tôi muốn thực thi một cái gì đó trong màn hình tách rời đó, nó sẽ kết thúc sau khi thực hiện xong. Tại sao? Tôi không thấy logic ở đây. Có thể có cửa sổ không làm gì, nhưng không thể có cửa sổ làm gì đó và sau đó không làm gì?
trejder

2
Khi bạn bắt đầu một cửa sổ mà không chỉ định một lệnh, nó không " không làm gì cả". "Cái gì đó" mà nó đang làm là chạy một vỏ tương tác, nó không thoát ra cho đến khi bạn thoát nó bằng tay.
jw013

Mát mẻ! Cảm ơn đã giải thích! Vì vậy, ... trở lại câu hỏi ... có cách nào để chạy lệnh bên trong màn hình / cửa sổ tách ra và KHÔNG kết thúc phiên đó, khi việc thực thi lệnh kết thúc? Ngoài ra, hãy xem câu hỏi cập nhật. Cảm ơn bạn.
trejder

Kịch bản lệnh này đang thực thi hai trình nghe UDP được viết bằng PHP. Mặc dù cả hai đều được thực thi dưới dạng daemon ( &ở cuối), do máy chủ bị lỗi (QNAP), chúng bị chấm dứt khi phiên kết thúc (tôi đã nói, chúng không nên chạy trên Linux bình thường, nếu được thực thi với &). Vì vậy, tôi không muốn làm bất cứ điều gì sau khi start_udp_listeners.shkết thúc, chỉ làm thế nào để ngăn chặn phiên bị chấm dứt. Miễn là không, trình nghe PHP của tôi vẫn hoạt động tốt.
trejder

Câu trả lời:


42

Để giữ cho màn hình bận rộn sau khi tập lệnh hoàn tất, chỉ cần giữ một cái gì đó liên tục chạy trong một cửa sổ. Sự lựa chọn đơn giản nhất cho "cái gì đó" có lẽ là một vỏ tương tác. Đây là một cách để làm điều đó (giả sử bashlà sự lựa chọn của vỏ tương tác):

screen -dmS session_name sh -c '/share/Sys/autorun/start_udp_listeners.sh; exec bash'
  • -dm: bắt đầu màn hình ở chế độ tách rời
  • -S: đặt tên phiên cho màn hình để truy xuất dễ dàng hơn sau này
  • sh -c '...': thay vì chỉ chạy tập lệnh của bạn, tập lệnh này sẽ chấm dứt, hãy sử dụng sh -cđể chạy nhiều lệnh
  • exec bash: sau khi tập lệnh kết thúc, shtừ bên trên sẽ chuyển sang shell tương tác ( bash), không bao giờ thoát ra cho đến khi một cái gì đó bên ngoài chấm dứt nó. Điều này sẽ tiếp tục screenmở miễn là bashcá thể còn sống.

1
Hừm ... dường như bạn là cứu tinh của đời tôi! :] Mở rộng giải pháp của bạn với export IGNOREEOF=1để ngăn chặn việc chấm dứt hợp đồng bằng Ctrl + D sẽ cho tôi giải pháp hoàn hảo, tôi đã tìm kiếm cả buổi tối dài. CẢM ƠN! :]
trejder

Điều này không hoạt động trên Debian cho đến ngày hôm nay, -c là một đối số để đọc tệp .screenrc thay thế ...
ToVine

@ToVine hoạt động hoàn hảo trên Debian Stable (Wheezy). Tôi đã sử dụng bash -cmặc dù.
translucentCloud

@TranslucentCloud bạn đã bao gồm toàn bộ lệnh "bash -c ..." trong dấu ngoặc kép? Lần cuối cùng tôi đã thử nó (ngay trước khi viết bình luận) nó không hoạt động với tôi, không chắc tại sao ...
ToVine

@ToVine đây là toàn bộ mệnh lệnh của tôi:screen -LS sauf bash -c "sudo aptitude update && sudo aptitude full-upgrade; exec bash"
translucentCloud

2

Tôi đã không gặp may mắn khi sh -ctrên raspberry pi 2 chạy Debian 7.8. Nhưng bash -cđã làm công việc:

Chỉ huy:

/usr/bin/screen -dmS test-screen bash -c "/usr/bin/top; exec bash"

Điều này có thể, bởi vì bạn đang sử dụng (trên Raspberry Pi) một lớp vỏ khác? Các bashshcó vẻ là hai vỏ khác nhau. Đó là tất cả, tôi nghĩ, nhưng tôi có thể sai, vì tôi là người mới sử dụng Linux.
trejder

1
sh là unix-shell mặc định, nó được bao gồm trong raspbian (debian). Lệnh sh cũng hoạt động, nhưng không kết hợp với màn hình.
scotty86

Cảm ơn bạn @ scotty86, tôi đã quan sát điều tương tự trong Linux Mint 19 (Ubuntu 18.04) và thay đổi sh -cđể bash -cthực hiện thủ thuật. Tôi không hiểu tại sao, cả hai shbashđược cài đặt, vì vậy tôi vẫn mất ngủ vì nó, nhưng ít nhất nó vẫn hoạt động.
Redsandro

shcó lẽ chỉ vào /bin/dashthay vì /bin/bash. Debian chuyển vỏ mặc định từ bashđể dashmột vài năm trước đây.
SCAI
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.