`<& -` làm gì?


20

Tôi đã sao chép một đoạn của Bash để làm nền một lệnh ssh được thực thi từ xa:

ssh user@remote <<CMD
some process <&- >log 2>error &
CMD

Không gì <&-làm gì?
Tôi đoán là nó giống như< /dev/null

Hiểu biết tiếp theo của tôi là ba mô tả tập tin chính ( stdin, stdout, stderr) cần phải được đóng lại để ngăn chặn:

  1. Công việc đang được làm nền và kịch bản thoát - xung đột bằng cách nào đó?
  2. Khi thiết bị đầu cuối đóng cửa, tất cả các quy trình chấp nhận stdin từ thiết bị đầu cuối được đóng lại?

Tham chiếu chéo bắt buộc: Xem Toán tử điều khiển và chuyển hướng của shell là gì? - mặc dù tất cả những gì nó nói về toán tử này là nó "có thể được sử dụng để đóng hoặc sao chép mô tả tệp" và bạn nên "xem phần có liên quan trong hướng dẫn sử dụng của shell".
G-Man nói 'Phục hồi Monica'

Nếu tôi nhớ lại chính xác, ssh -nNT user@remote 'command'sẽ tạo một phiên SSH không tương tác. Nối &đến nền nó, hãy thêm nohupvào commandđể giữ cho nó chạy nếu chết kết nối của bạn.
Mark K Cowan

1
@MarkKCowan man sshđề xuất rằng -N không cho phép chạy hoàn toàn một lệnh từ xa và kiểm tra nhanh hỗ trợ điều đó.
Tom Hunt

À đúng rồi, tôi đã sử dụng -nNTR để chuyển tiếp cổng ngược. Bỏ qua -N và -R rồi :)
Mark K Cowan

Câu trả lời:


30

<&-không phải là khá điều tương tự như < /dev/null. <&-đóng fd 0, trong khi < /dev/nullchuyển hướng nó từ thiết bị /dev/null, không bao giờ cung cấp bất kỳ dữ liệu nào và luôn cung cấp EOF khi đọc. Sự khác biệt chủ yếu là một read(2)cuộc gọi từ một FD đóng ( <&-trường hợp) sẽ lỗi với EBADF, trong khi đó một cuộc gọi từ FD được chuyển hướng null sẽ trả về không đọc byte (điều kiện cuối tập tin). Nếu chương trình của bạn không bao giờ đọc từ stdin, thì sự khác biệt không thành vấn đề.

Đóng các FD là một cách thực hành tốt nếu bạn đang làm nền một cái gì đó, vì một quá trình nền sẽ bị treo nếu nó cố đọc bất cứ thứ gì từ TTY. Ví dụ này không xử lý đầy đủ mọi thứ cần thiết; lý tưởng là sẽ có một nohuphoặc setsidgọi ở đâu đó, để tách rời hoàn toàn quá trình nền.


Vì vậy, tôi nên sử dụng nohupngoài việc đóng mô tả tập tin?
Eric Francis

2
Phương pháp kỹ lưỡng nhất (bắt chước cách các chương trình tự tạo ra) là một cái gì đó như thế setsid some process <&- >path/to/log 2>path/to/error. Phương pháp nhanh hơn là một cái gì đó như nohup some process &.
Tom Hunt

2
@EricFrancis: Sử dụng nohupkhông có ý nghĩa ở đây. nohupngăn quá trình nhận HUPtín hiệu khi thiết bị đầu cuối điều khiển của nó đóng lại. Nhưng bạn đã không có bất kỳ thiết bị đầu cuối trong trường hợp này.
cuonglm

@TomHunt: Quá trình nền không bị treo, phiên ssh đã làm.
cuonglm

2
không phải là một ý tưởng tốt để đóng fds 0, 1 & 2 ... bạn không muốn fd tiếp theo được tạo để chiếm một trong những giá trị đó. tốt hơn để chuyển hướng chúng đến / dev / null
Murray Jensen

7

Xem man bash:

  [n]<&word

được sử dụng để sao chép mô tả tập tin đầu vào. Nếu wordmở rộng thành một hoặc nhiều chữ số, bộ mô tả tệp được biểu thị bởi nđược tạo thành một bản sao của bộ mô tả tệp đó. Nếu các chữ số trong word không chỉ định mô tả tệp mở cho đầu vào, sẽ xảy ra lỗi chuyển hướng. Nếu từ ước tính -, mô tả tập tin nđược đóng lại. Nếu nkhông được chỉ định, đầu vào tiêu chuẩn (mô tả tệp 0) được sử dụng.


Định nghĩa đúng là không xác định được những gì xảy ra khi bạn có [n]<&wordvà từ chứa nhiều hơn một chữ số.
schily

Ý anh là gì? Là man bashkhông chính xác?
Eric Francis

@EricFrancis vì nó không được chỉ định trong tiêu chuẩn, bashchọn thực hiện nó theo cách lành mạnh (đối với một số định nghĩa phù hợp về "lành mạnh"). Vỏ khác có thể hoặc không thể làm như vậy.
muru

@muru Câu hỏi được gắn thẻ bash, không posix-shell.
Barmar

@Barmar ok. Vì thế...?
muru

7

<&- đóng chuẩn đầu vào.

Các hình thức nói chung, được định nghĩa bởi POSIX , là:

[n]<&word

Mục đích của nó để tạo mô tả tệp nlà một bản sao của mô tả tệp được biểu thị bởi word. Tiêu chuẩn trong được giả sử nếu nbị bỏ qua và nếu word-, bộ mô tả tệp nsẽ bị đóng.

Nó không giống như </dev/null, vì trong trường hợp </dev/null, đầu vào tiêu chuẩn vẫn mở và được chuyển hướng đến nơi khác.

Bạn cần đóng tất cả các mô tả tệp của các quy trình được gắn vào ổ cắm ssh, nếu không, phiên ssh không thể đóng.

Bạn có thể chạy lệnh trên máy từ xa mà không cần gắn nó vào phiên ssh, bằng cách sử dụng màn hình hoặc tmux :

ssh user@remote 'screen -S test -d -m command'

Tại sao bỏ phiếu xuống?
cuonglm
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.