2009-06-26 17 views
7

Tôi đang viết một bộ lọc (trong một đường ống dành cho đầu ra đầu cuối) đôi khi cần "ghi đè lên" một dòng vừa mới xảy ra. Nó hoạt động bằng cách truyền stdin đến stdout character-by-ký tự cho đến khi đạt được \n và sau đó gọi hành vi đặc biệt. Vấn đề của tôi liên quan đến cách quay lại đầu dòng.Trả về con trỏ thiết bị đầu cuối để bắt đầu dòng với gói được kích hoạt

Điều đầu tiên tôi nghĩ đến là sử dụng \r hoặc trình tự ANSI \033[1G. Tuy nhiên, nếu đường dây đủ dài để quấn trên thiết bị đầu cuối (và do đó làm cho nó cuộn), chúng sẽ chỉ di chuyển con trỏ trở lại dòng vật lý hiện tại.

Ý tưởng thứ hai của tôi là theo dõi độ dài của dòng (số ký tự được chuyển từ trước đó), và sau đó echo \b nhiều lần. Tuy nhiên, điều đó sai nếu dòng chứa các ký tự điều khiển hoặc các chuỗi thoát (và có thể là Unicode?).

Thiếu tìm kiếm tất cả các chuỗi đặc biệt và sử dụng điều này để điều chỉnh số ký tự của tôi, có cách nào đơn giản để đạt được điều này không?

Trả lời

0

Bạn có thể truy vấn kích thước thiết bị đầu cuối với một đơn giản ioctl:

#include <sys/types.h> 
#include <sys/ioctl.h> 

// ... 

struct winsize ws; 
ioctl(1, TIOCGWINSZ, &ws); 

// ws.ws_col, ws.ws_row should now contain terminal dimensions 

Bằng cách này bạn có thể ngăn chặn in bất cứ điều gì vượt ra ngoài cuối dòng và chỉ đơn giản là sử dụng phương pháp \r.

+0

Cảm ơn bạn đã đề xuất! Thật không may có một vài lý do tại sao tôi không nghĩ rằng sẽ làm việc cho tôi: * Tôi vẫn cần phải theo dõi trình tự trường hợp đặc biệt để biết làm thế nào gần với cạnh Tôi * Tôi có thể không phải là điều cuối cùng trong đường ống Đối với ngữ cảnh; bộ lọc của tôi phù hợp với mẫu và các chuỗi phù hợp "viết lại" được bao quanh trong chuỗi thoát màu. Tôi không thể sử dụng 'fgets()' và hoạt động trên toàn bộ chuỗi tại một thời điểm, vì một số đầu vào của tôi sẽ tạo ra đầu ra "động" (ví dụ: trạng thái tiến trình tăng) không xuất ra '\ n' trong một thời gian. –

0
 
$ cat >test.sh <<'EOF' 
> #!/bin/sh 
> tput sc 
> echo 'Here is a really long multi-line string: .............................................................................................' 
> tput rc 
> echo 'I went back and overwrote some stuff!!!!' 
> echo 
> EOF 
$ sh test.sh 
I went back and overwrote some stuff!!!! ....................................... 
...................................................... 

Look cho các khả năng save_cursorrestore_cursor chuỗi trong cơ sở dữ liệu terminfo.

+0

Hiểu biết của tôi là rc và sc lưu vị trí * vật lý * của con trỏ (tương đương với \ 033 [s và \ 033 [u). Nếu toàn bộ nội dung của thiết bị đầu cuối cuộn do dòng bọc, đầu chuỗi không còn ở cùng vị trí vật lý nữa. (Ít nhất, đây là hành vi tôi quan sát trong xterm.) –

+0

Ah, điều đó dường như cũng xảy ra trong thiết bị đầu cuối của tôi. Aww ... – ephemient

4

Thậm chí nếu có "chuỗi ma thuật" khi ghi vào bàn điều khiển sẽ xóa dòng văn bản cuối cùng, bạn vẫn có thể nhận được dòng và chuỗi trên đầu ra (mặc dù bị ẩn trên bảng điều khiển). Hãy nghĩ điều gì sẽ xảy ra nếu ai đó viết đầu ra cho một tập tin, hoặc truyền nó xuống ống dẫn đến các bộ lọc khác? Họ có biết cách xử lý đầu vào như vậy không? Và đừng nói với tôi rằng bạn loại trừ khả năng viết ở đâu đó khác hơn là trực tiếp vào bàn điều khiển. Sớm hay muộn, ai đó S to muốn chuyển hướng đầu ra - thậm chí có thể bạn!

Cách đúng để thực hiện việc này là để đệm mỗi dòng trong bộ nhớ khi nó được xử lý, và sau đó quyết định có nên xuất nó hay không. Có thực sự không có cách nào xung quanh này.

+0

Thật vậy, đó là giải pháp ban đầu của tôi. Nơi duy nhất phá vỡ là cho các công cụ như tỷ lệ phần trăm tiến độ tăng dần theo thời gian (tự ghi đè bằng \ b), trong đó không có \ n trong vài giây hoặc vài phút, do đó, fgets() và cứ như vậy trong một khoảng thời gian đáng kể.Ngẫu nhiên, tôi đã giảm khả năng bộ lọc của tôi không phải là thứ cuối cùng trong đường ống (mặc dù những gì tôi đã nói trong một nhận xét trước đó), vì không có lý do gì để sử dụng nó ngoài công cụ để tạo đầu ra giao diện điều khiển! –

+0

Nhận xét nhanh về việc là mục cuối cùng trong đường ống: bạn không thể chắc chắn rằng thiết bị xuất chuẩn đi đến một thiết bị đầu cuối, như 'ls' có hoạt động không? –