Hiển thị thiết bị xuất chuẩn của một quá trình nền ở vị trí cụ thể của thiết bị đầu cuối


8

Tôi có một lệnh mà tôi chạy mỗi khi thiết bị đầu cuối mới được mở hoặc đăng nhập mới được thực hiện.

Chương trình này tạo đầu ra (màu) nên được định vị trước dấu nhắc lệnh. Có thể mất vài giây để chạy, điều đó sẽ ngăn tôi sử dụng thiết bị đầu cuối cho đến khi đó (trừ khi chạy ở chế độ nền).

Được cung cấp hơn zsh có một số cách nâng cao để vẽ lại thiết bị đầu cuối mà không ghi đè văn bản hiện có, tôi muốn biết làm thế nào tôi có thể chạy lệnh này theo cách mà tôi không phải đợi nó kết thúc trước khi tôi có thể sử dụng thiết bị đầu cuối nhưng điều đó một khi nó hoàn thành nó sẽ in đầu ra như thể nó không được làm nền ở vị trí đầu tiên.

Trong thực tế tôi muốn một cái gì đó có thể làm:

Command output:
... (running on background)
me@computer: somecommand
me@computer: someothercommand

và một khi lệnh kết thúc tôi sẽ nhận được:

Command output:
 * Output foo
 * Multiple lines bar
 * and some yada
me@computer: somecommand
me@computer: someothercommand

Tôi đã thử đặt quá trình ở chế độ nền khi bắt đầu nhưng sau đó nó không hiển thị đầu ra rõ ràng. Tôi nhận được một cái gì đó như:

Command output:
[2] 32207
me@computer: somecommand
me@computer: someother * Output foo
 * Multiple lines bar
 * and some yada
[2]  + done       command
me@computer: someothercommand

Vì vậy, điều này là có thể? Nếu không với zsh thì có giải pháp nào ngoài đó có thể làm được không?

Bất kỳ con trỏ hoặc thông tin đều được chào đón.


Không thể nếu chương trình đang chạy trực tiếp trong thiết bị đầu cuối, vì chỉ có một vị trí con trỏ và zsh và chương trình sẽ cạnh tranh với nó. Bạn có thể làm một cái gì đó với zpty: có lệnh chạy trong một thiết bị đầu cuối được tạo bởi zsh, với đầu ra của nó được chuyển tiếp đến thiết bị đầu cuối thực sự dưới sự kiểm soát của zsh.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles Bạn có thể giải thích về cách sử dụng zpty? Tôi biết rằng bạn không thể có hai chương trình ghi vào cùng một thiết bị đầu cuối mà không có sự cạnh tranh nào với con trỏ. Câu hỏi của tôi xuất phát từ thực tế là zsh đã viết lại lời nhắc trong một số cấu hình. Rõ ràng chương trình này sẽ phải ghi vào một số bộ đệm trong bộ nhớ tạm thời sau đó sẽ được "in" đến vị trí cụ thể sau khi lệnh kết thúc. Tất cả sau này dưới sự kiểm soát của zsh.
giải mã

@Gilles: có lẽ đây là một câu trả lời thực sự?
Stéphane Gimenez

@ StéphaneGimenez Chắc chắn rồi. Tôi không biết làm thế nào để thực hiện nó mà không cần một số nghiên cứu và tôi không có thời gian cho nghiên cứu này ngay bây giờ.
Gilles 'SO- ngừng trở nên xấu xa'

Một ý tưởng sẽ là thực hiện điều này với screenmột kịch bản khởi động chia đôi màn hình và chạy trình chạy dài ở phần trên và dòng lệnh bình thường ở phần dưới.
vasquez

Câu trả lời:


5

Đây là một giải pháp đơn giản nếu bạn sẵn sàng chấp nhận đầu ra ngay phía trên dòng nhắc hiện tại.

TRAPUSR1 () { zle -I; unfunction TRAPUSR1 }  # invalidate prompt on signal USR1

bufferout () {
    local buffer
    while read -r line; do                   # buffer lines from stdin
        buffer="$buffer$line\n"
    done
    print -rn -- $terminfo[dl1]              # delete current line
    print -rn -- $terminfo[cr]               # move cursor to BOL
    printf "$buffer"                         # print buffer
    kill -USR1 $$                            # send USR1 when we're done
}

unsetopt monitor                             # don't monitor this job
./testout |& bufferout & disown              # bg and disown to suppress notification
setopt monitor                               # restore job monitoring

Khi công việc hoàn thành, bộ đệm nhắc nhở và đầu vào hiện tại sẽ bị xóa và toàn bộ lệnh stdoutstderrsẽ được in.

Bạn có thể trở nên lạ mắt hơn nhiều so với zsh/cursesmô-đun, nhưng tôi nghi ngờ rằng nó sẽ cung cấp một lợi thế đủ đáng kể để xứng đáng với nỗ lực này.


Những công việc này. Nhưng làm thế nào khó khăn để ngăn vỏ in ra pid quá trình khi được gửi đến nền và thông báo "hoàn thành" sau khi hoàn thành? (Ý tôi là tạm thời hủy kích hoạt tính năng đó). Ngoài ra, trước khi đặt đầu ra trên thiết bị đầu cuối, việc xóa dòng nhắc hoặc dòng hiện tại sẽ khó đến mức nào?
giải mã

Tôi nghĩ rằng tôi có thể có một số cấu hình viết lại nhắc nhở khác đang va chạm với việc xóa dấu nhắc ban đầu. Của tôi không biến mất một khi lệnh kết thúc. Tôi cũng vẫn nhận được các PID của các quá trình khi được gửi đến nền nhưng dòng "xong" đã biến mất. Trong mọi trường hợp, tôi chấp nhận câu trả lời của bạn vì nó khá gần với những gì tôi nghĩ. Cảm ơn.
giải mã

Tôi đang sử dụng xterm và tôi đã bật mô-đun VCS và một số tùy chỉnh khác cho lời nhắc. Tôi đã không thử nhưng tôi khá chắc chắn rằng nó liên quan đến điều đó. Cách đây một thời gian, tôi đã thử sử dụng trình thông báo chế độ vi tương tự như trình thông báo này ( stackoverflow.com/a/3791786/125801 ) và khi kích hoạt tôi đã mất một số hành vi nhắc nhở tùy chỉnh của mình. Đó không phải là một vấn đề lớn, tại thời điểm này tôi hài lòng với giải pháp. Tôi sẽ cố gắng dọn sạch lời nhắc của mình một trong những ngày này và kiểm tra xem các PID vẫn còn hiển thị hay không.
giải mã

Zsh-4.3.10, sau khi vô hiệu hóa khá nhiều tùy chỉnh, giờ đây tôi không còn nhận được lời nhắc (nghĩa là đã xóa đúng cách) nhưng tôi vẫn nhận được các PID của các quy trình ở chế độ nền, như [1] 27911 27912trong một dòng duy nhất và là dòng đầu tiên trên dòng thiết bị đầu cuối.
giải mã

Tôi có thể upvote một lần nữa? :) Bây giờ thật hoàn hảo! Cảm ơn nhiều.
giải mã
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.