Tại sao 'lệnh nohup> & / dev / null' dường như làm việc trên mạng trong một số shell?


12

Tôi đã chỉnh sửa câu trả lời trên Hỏi Ubuntu đã gợi ý như sau

nohup gedit >& /dev/null & 

Khi họ thực sự có nghĩa là

nohup gedit &> /dev/null & 

Cái sau chuyển hướng chính xác cả stderr và stdout đến /dev/null. Tôi đã hy vọng trước đây sẽ tạo một tệp có tên &hoặc, nhiều khả năng, sẽ gây ra lỗi như trong các trường hợp khác:

$ echo "foo" >& 
bash: syntax error near unexpected token `newline'

Thay vào đó, nó dường như hoạt động chính xác như trước đây, một geditcửa sổ xuất hiện và không có thông báo lỗi được in.

Tôi cũng cần lưu ý rằng đây là vỏ cụ thể:

  • bash(4.2.45 (1) -release), zsh(5.0.2), csh(phiên bản gói deb: 20110502-2) và tcsh(6.18.01): hoạt động như mô tả ở trên, không có thông báo lỗi, không tạo tệp.

  • dash (0,5,7-3):

    $ nohup gedit >& /dev/null & 
    $ dash: 2: Syntax error: Bad fd number
  • ksh(93u + 2012-08-01): thất bại, nhưng một quá trình rõ ràng đã bắt đầu ( 1223) mặc dù không có geditcửa sổ nào xuất hiện:

    $ nohup gedit >& /dev/null & 
    [1] 1223
    $ ksh: /dev/null: bad file unit number
  • fish (2.0.0):

    > nohup gedit >& /dev/null & 
    fish: Requested redirection to something that is not a file descriptor /dev/null
    nohup gedit >& /dev/null & 
                   ^

Vì vậy, tại sao lệnh này chỉ đơn giản chạy mà không có lỗi (và không có tệp đầu ra được tạo) trong một số shell và thất bại trong những cái khác? Việc >&làm trong trường hợp đặc biệt rõ ràng là nohupgì? Tôi đoán điều đó >& /dev/nullđang được hiểu là >&/dev/nullnhưng tại sao không gian lại gây ra lỗi trong các shell này?


Trong máy của tôi, Ubuntu 12.04, lệnh này chạy bình thường cho dash.
cuonglm

nohup command, Chạy tty độc lập application.According của bạn vào bộ nhớ của tôi, dashmở rộng của ash, Debian ash, ashđược phát triển bởi OpenBSDvà đó là vỏ hạn chế, ngay cả hệ điều hành maemo (Debian Dựa trên N900 điện thoại di động) sử dụng dấu gạch ngang, ashvỏ gia đình có sử dụng hạn chế mong đợi của bash hoặc tcsh.
Tiếng

@Gnouc huh, có lẽ là một phiên bản khác (tôi đang sử dụng Debian)? Tôi không thể tìm ra cách để tôi dashin phiên bản của nó ra nhưng gói là 0.5.7-3, cái gì là của bạn? Ngoài ra, bạn có chắc là bạn đang chạy dash? Đó là mặc định của Ubuntu shphải không?
terdon

@MohsenPahlevanzadeh Tôi không chắc quan điểm của bạn là gì, tôi biết điều nohupđó xảy ra, câu hỏi của tôi là tại sao >&dường như hoạt động với nohup một mình trong một số vỏ.
terdon

Bạn có thể sử dụng liên kết sau để xem abstarct của shell: unix.stackexchange.com/questions/45684/iêu
Ba TưGulf

Câu trả lời:


18
nohup gedit &> /dev/null

là cú pháp POSIX và giống như:

nohup gedit &
> /dev/null

Đó là chạy nohup gedittrong nền và sau đó thực hiện > /dev/nullchuyển hướng mà không chạy lệnh.

nohup gedit >& /dev/null

không phải là cú pháp POSIX và là cshcách để chuyển hướng cả thiết bị xuất chuẩn và thiết bị xuất chuẩn thành / dev / null. cshkhông có 2>&1toán tử như được tìm thấy ở Bourne, vì vậy đó là cách duy nhất cshđể chuyển hướng stderr.

zsh(như thường lệ) cũng cung cấp cshcú pháp, nhưng nó cũng hỗ trợ toán tử x>&y sao chép fd của trình bao Bourne, có nghĩa là có xung đột ở đó.

ls >&file

chuyển hướng lsstdout và stderr sang file, nhưng nếu tập tin là 2, bạn đã gặp vấn đề như

ls >&2

có nghĩa là chuyển hướng xuất chuẩn đến tài nguyên được chỉ ra bởi fd 2 ( dup(2, 1)). Vì vậy, bạn cần phải viết nó:

ls >& ./2

nếu bạn muốn chuyển hướng cả thiết bị xuất chuẩn và thiết bị xuất chuẩn lsvào một tệp được gọi 2trong thư mục hiện tại; hoặc sử dụng cú pháp tiêu chuẩn.

bashban đầu không hiểu >&, nhưng nó đã giới thiệu &>toán tử thay vào đó, phá vỡ sự tuân thủ POSIX trong quy trình (mặc dù không chắc là tập lệnh sẽ sử dụng cmd &> xxx).

kshđã sao chép toán tử đó trong ksh93t + vào năm 2009, mksh trong R35 năm 2008 (bị tắt trong posixchế độ) nhưng không >&.

bashhỗ trợ thêm >&trong 2.05.

busybox shđã thêm hỗ trợ cho cả hai &>>&trong 1.13 (2008).

Cả stdout và stderr đều >&không &>có nghĩa là POSIX / Bourne.

Nếu bạn muốn chuyển hướng cả stdout và stderr một cách hợp lý, cú pháp là

cmd > file 2>&1

Ý bạn là Bash trong POSIX/Bourne"Bourne"?
Pandya
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.