Xem qua nội dung của stdin


7

Tôi đang cố gắng gỡ lỗi một ứng dụng Linux có thể nhận lệnh thông qua stdin và sẽ rất hữu ích khi có thể thấy mọi thứ được ghi vào stdin.

Cách tiếp cận đầu tiên của tôi là thực thi sudo cat /proc/$pid/fd/0, nhưng hóa ra đó là một cách tiếp cận không hợp lệ, vì cả hai catvà quá trình của tôi đang cố gắng tiêu thụ nội dung của bộ mô tả tệp đó và chỉ có một quy trình có thể giành chiến thắng trong cuộc đua.

Một cách tiếp cận khác là sử dụng đuôi, nhưng điều đó sẽ không hiệu quả vì những lý do được nêu ở đây .

Tôi có thể dễ dàng thêm ghi nhật ký gỡ lỗi vào ứng dụng của mình và điều đó sẽ giải quyết được vấn đề, nhưng tôi rất muốn biết liệu có cách tiếp cận tổng quát hơn mà tôi đang thiếu hay không.


câu hỏi tuyệt vời ! Đã thử làm điều tương tự như bạn theo nghĩa đen ngày hôm qua và viola - có một câu hỏi.
Sergiy Kolodyazhnyy

Câu trả lời:


3

strace ?

Ví dụ dưới đây. Bắt đầu một quá trình mèo đang đọc stdin và viết vào / tmp / faggerile. Tìm pid, strace nó. Và trong cửa sổ mèo ban đầu, hãy nhập một số văn bản, xin chào.

# cat >/tmp/foofile


# ps -ef|grep cat
steve     2134  1801  0 22:25 pts/2    00:00:00 cat
# strace -fp 2134
Process 2134 attached
read(0, "test\n", 65536)                = 5
write(1, "test\n", 5)                   = 5
read(0,

Để lấy ra các lần đọc từ mô tả tệp 0:

strace -fp 2134 -e trace=read -o "|grep read.0,"

Cám ơn vì sự gợi ý. Bạn có biết một cách để làm cho nó in ra các chuỗi dài hơn? $ Strace -fp pidof catProcess 25.975 kèm theo - ngắt để quit đọc (0, "afdkjdjakskljjjjjjjjjjjjjjjjjjjj" ..., 32768) = 4096 ghi (1, "afdkjdjakskljjjjjjjjjjjjjjjjjjjj" ..., 4096) = 4096 đọc (0 Cảm ơn, John
John Saxton

1
À, có vẻ như có một tham số "-s" sẽ thực hiện thủ thuật.
John Saxton

1
Lệnh hiện tại của tôi là strace -s 4096 -e trace=read -fp 26471. Quá trình tôi gỡ lỗi thực hiện rất nhiều I / O bổ sung, vì vậy tôi đang cố gắng đưa ra một cách để lọc để nó chỉ in các lệnh đọc từ stdin chứ không phải các mô tả tệp khác. Tôi chắc chắn sẽ đăng một bản cập nhật khi tôi tìm ra nó.
John Saxton

@JohnSaxton -e read=0cung cấp cho bạn một kết xuất tốt của chỉ đầu vào tiêu chuẩn.
Gilles 'SO- đừng trở nên xấu xa'

Cảm ơn Steve đã cập nhật câu trả lời để bao gồm -o "|grep read.0,". Lệnh cuối cùng tôi đang sử dụng là strace -s 4096 -e trace=read -fp $pid -o "|grep read.0,". Tôi hơi lo ngại vì hiệu suất đạt được liên quan đến strace, nhưng đây là giải pháp tốt nhất tôi có thể đưa ra, vì vậy tôi sẽ đánh dấu đây là câu trả lời được chấp nhận.
John Saxton

0

Trên linux, bạn có thể xử lý các mô tả tệp của ứng dụng như các tệp được đặt tên trong /dev/fd/[0-9]. Và những gì bạn chắc chắn có thể làm với một tệp có tên và luồng đầu vào là teeđầu vào vào tệp đó xuất ra. Và vì vậy, những gì tôi thường làm khi thấy mình trong tình huống của bạn (như tôi thường làm)teeđầu vào cho cả ứng dụng đọc của tôi và to /dev/fd/2- stderr.

Như thế này:

seq 10 | tee /dev/fd/2 | wc -c
1
2
3
4
5
6
7
8
9
10
21

Tất nhiên, ngay cả khi bạn không sử dụng hệ thống linux, điều tương tự cũng có thể được thực hiện - nếu ít cụ thể hơn trong một số trường hợp - chỉ bằng cách thực hiện ...| tee /dev/tty | ...

Nếu bạn đang nói về thiết bị đầu cuối khi bạn nói stdin (như liên kết của bạn chỉ ra) , thì bạn vẫn có thể làm điều tương tự, mặc dù điều đó có thể khó khăn hơn một chút vì cách đệm dòng của hạt nhân. Và vì vậy, những gì tôi sẽ làm trong trường hợp đó là đăng nhập tất cả ttyi / o bằng cách gói lệnh của tôi vào luit- bởi vì tôi thấy nó thuận tiện hơn trong hai mặc dù scriptcũng có thể hoạt động theo cách tương tự.

luitcó lẽ đã được cài đặt trên hệ thống của bạn - nó thường được đóng gói w / xterm- và nó là một công cụ cli rất đơn giản nhằm thực hiện các bản dịch UTF-8 (chức năng này có thể bị vô hiệu hóa hoàn toàn thông qua chuyển đổi cli, nhưng tôi chưa bao giờ tìm thấy lý do để làm như vậy) cho các ứng dụng đầu cuối không hiểu nó.

Nó hoạt động bằng cách xếp lớp pty của riêng nó - mà nó sở hữu fd chính - bên dưới lớp tty hiện tại và sao chép tất cả i / o từ phiên hiện tại sang lớp con của nó, nơi nó thực thi ứng dụng bạn yêu cầu. Bởi vì nó sở hữu đầu cuối chính, nó có thể dễ dàng sao chép tất cả i / o nó đọc / ghi ở nơi khác nếu muốn và nó cung cấp một phương tiện thuận tiện để yêu cầu nó làm như vậy:

luit -olog /dev/fd/2 sh -c 'read var; echo "$var"'
eecchhoo  tthhiiss  vvaarr??????

echo this var???
echo this var???

Ở đâu, như bạn có thể thấy, luitghi nhật ký vào -ologtệp có tên của nó, tất cả đầu vào đầu cuối nhận được ngay khi có.

Việc sử dụng /dev/fd/2gần như không hữu ích trong trường hợp đó - vì tất cả các i / o kết thúc ở cùng một nơi hai lần. Tôi thường thích mở một terminal thứ hai, truy vấn tên của nó với các ttylệnh, và sử dụng rằng /dev/pts/[0-9]tên như luit/ script's tên outfile - mà sẽ sao chép tất cả các I / O cho cả hai thiết bị đầu cuối đồng thời - vì vậy tôi có thể đọc / xem lại nó trên một và tương tác với nó trên mặt khác. teecó thể được sử dụng để làm điều tương tự trong hầu hết các trường hợp, nhưng nó thường không có lợi thế là kết thúc chính của một pty để giới thiệu nó.

Nếu mục đích của bạn giống như bạn nói - để sao chép để xem xét tất cả đầu vào của một số quy trình - thì có lẽ bạn sẽ làm tốt nhất để tập trung vào đầu vào. stracelà hữu ích cho nhiều thứ, nhưng nếu bạn đang cố gắng để có được một báo cáo chính xác về hành vi điển hình, thì lý do là bạn có thể nên sửa đổi hành vi đó ít nhất có thể trong khi thu thập báo cáo của mình. Nói cách khác, nếu bạn muốn nhập liệu, sao chép đầu vào, đừng chèn quy trình gỡ lỗi cha mẹ và sẽ -TRAPtạm dừng quy trình của bạn mỗi khi nó tạo ra một tòa nhà.


-1

Một khả năng (nếu điều đó không phá vỡ những thứ khác) là chèn một cuộc gọi đến tee. Lệnh teesao chép dữ liệu, do đó bạn có thể có một bản sao vào ứng dụng của mình và một bản sao đi đến đầu ra gỡ lỗi. Thay vì gọi your_application, hãy sắp xếp để gọi tee input.log | your_application. Nếu đầu vào cho ứng dụng của bạn là một tệp, thì đây không phải là một thay đổi xâm lấn, nhưng nếu đó không phải là một đường ống, điều đó làm cho nó trở thành một đường ống dẫn đến hậu quả (ví dụ như đường ống không thể tìm kiếm được).

Một khả năng khác là theo dõi các hoạt động đọc tệp mà ứng dụng của bạn thực hiện. Bạn có thể làm điều này với strace :

strace -e read=0 -e trace=read -e signal=none your_application 2>&1 |
grep '^ |'
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.