Viết cho stdin của quá trình nền


25

Tôi đang sử dụng hộp Ubuntu 10.04 và đã khởi động máy chủ ở chế độ nền (myserver &) qua ssh. Nó đang chạy tốt, nhưng tôi cần một cách để truy cập vào stdin của máy chủ, vì cách duy nhất để kiểm soát máy chủ là thông qua phương thức này.

Có cách nào để đạt được quy trình đang chạy để tôi có thể viết cho nó (và hy vọng đọc được thiết bị xuất chuẩn của nó) không? Rõ ràng, nếu tôi sẽ thực hiện điều này ngay bây giờ, tôi sẽ bắt đầu nó với một bộ chuyển hướng FIFO sang stdin, nhưng tiếc là bây giờ đã muộn một chút.

Có ý kiến ​​gì không?


Bạn không thể mang nó trở lại nền trước sao? ('công việc' sẽ liệt kê quy trình nền hiện tại của bạn, 'fg $ X' sẽ đưa công việc trở lại nền trước, ctrl + b sẽ tạm dừng công việc và đưa bạn trở lại trình bao của mình, trong khi 'bg' sẽ tiếp tục quá trình tạm dừng trong nền)
symcbean

Câu trả lời:


10

Bạn có thể thử viết vào thư mục của nó / Proc pid. Giả sử pid của daemon của bạn là 2000, hãy thử viết thư cho / Proc / 2000 / fd / 0


Cảm ơn ... tôi đã tìm thấy điều đó ngay sau khi tôi đăng bài này (sau một ngày tìm kiếm - điển hình). Điều đó dường như hoạt động (theo như thực sự gửi dữ liệu đến chương trình). Thật không may, chương trình không chấp nhận các lệnh. Tôi đã kiểm tra nó chạy máy chủ trên máy tính cục bộ của tôi và chắc chắn, tôi thấy dữ liệu xuất hiện, nhưng chương trình không nhận ra các lệnh. Tôi phải nhấn thủ công enter trên thiết bị đầu cuối máy chủ, và sau đó nó chỉ nói lệnh không được nhận dạng. Có lẽ một số kỳ lạ java? Tôi bị kẹt ...
tajmorton

1
Làm thế nào về echo -e "cái gì đó \ n"> / Proc / 2000 / fd / 0?
katriel

Trên thực tế, điều này không phải là thay đổi như / Proc / <pid> / fd / 0 điểm đến / dev / pts <một số số> trên ít nhất một số hệ thống ...
bk138 17/03/2015

Câu trả lời đầu tiên cho serverfault.com/questions/178457/ Ghi chú rằng phương pháp này không thực sự hiệu quả.
barrycarter

2
Điều này không thực sự hoạt động. Shell của bạn bình thường (khi không có đường ống hoặc chuyển hướng nào được sử dụng) bắt đầu một lệnh với các bộ mô tả tệp 0thông qua 2được đặt thành cùng một tệp, thường là một thiết bị đầu cuối ảo (đại loại như /dev/pty/...). Sau đó, lệnh sẽ đọc từ FD 0ghi vào FD 12để giao tiếp với thiết bị đầu cuối ảo (ví dụ: qua SSH hoặc trực tiếp với trình giả lập thiết bị đầu cuối của bạn). Nếu bất kỳ quá trình nào khác truy cập vào tệp đó (ví dụ thông qua /proc), chính xác điều tương tự sẽ xảy ra, tức là ghi vào nó ghi vào thiết bị đầu cuối và không vào lệnh.
Feuermurmel

29

Bạn có thể khởi động máy chủ của mình với một ống có tên (fifo) làm đầu vào của nó:

mkfifo /tmp/srv-input
cat > /tmp/srv-input &
echo $! > /tmp/srv-input-cat-pid
cat /tmp/srv-input | myserver &

Điều cat > /tmp/srv-input &quan trọng là tránh máy chủ của bạn nhận EOF. Ít nhất một quy trình phải mở fifo bằng văn bản để máy chủ của bạn không nhận được EOF. PID của lệnh này được lưu trong /tmp/srv-input-cat-pidtệp để giết sau.

Trong trường hợp bạn đã khởi động máy chủ của mình, bạn phải sử dụng trình gỡ lỗi, chẳng hạn như gdbđể đính kèm vào quy trình của bạn để chuyển hướng nó stdinđến fifo:

gdb -p PID
call close(0)
call open(0, "/tmp/srv-input", 0600)

Và sau đó làm một cái gì đó như dưới đây để gửi đầu vào đến máy chủ của bạn (trong một cửa sổ đầu cuối khác nếu cần thiết):

echo "command" > /tmp/srv-input

Để gửi EOF đến máy chủ của bạn, bạn cần phải hủy cat > /tmp/srv-inputquá trình mà PID đã được lưu trong /tmp/srv-input-cat-pid file.

Trong trường hợp GDB, chỉ cần thoát GDB và EOF sẽ được gửi.


1
đây là một cách tiếp cận di động hơn nhiều so với cách tiếp cận từ @katriel vì / Proc / 2000 / fd / 0 không phải là stdin trên tất cả các hệ thống.
Prior99

Thủ thuật với "cat> / tmp / srv-input &" đã giúp tôi đỡ đau đầu. Cảm ơn bạn!
Prior99

Thế còn mkfifo /tmp/srv-input; tail -f /tmp/srv-input | myserver &? Điều này cũng sẽ giữ cho đường ống mở ...
bk138

@ bk138: có vẻ như đuôi của tôi hoạt động, nhưng chỉ có một cách để biết chắc chắn: kiểm tra.
jfg956 17/03/2015

tailkhông hoạt động, nhưng đã thêm nó để hoàn thành công việc: cat /tmp/srv-input | myserver; kill -9 cat / tmp / srv-input-cat-pid` && rm / tmp / srv-input-cat * `
Thiago Macedo

4

Tương tự như trên, nhưng 'con mèo' không làm việc với tôi. Các tập tin đã nhận EOF và kết thúc sau khi gửi một lệnh.

Điều này làm việc cho tôi:

#!/bin/bash

mkfifo /tmp/srv-input
tail -f /tmp/srv-input | myserver &
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.