Những gì mà 2 2 & & 1 làm gì trong dòng lệnh?


59

Tôi biết rằng >dấu hiệu được sử dụng để chuyển hướng đầu ra trong dòng lệnh, nhưng tôi gặp khó khăn khi tìm thứ gì đó giải thích việc sử dụng 2>&1trong dòng lệnh. Ví dụ:

curl http://www.google.com > /dev/null 2>&1 &

Câu trả lời:


78

Các 1biểu thị đầu ra tiêu chuẩn (stdout). Các 2biểu thị lỗi tiêu chuẩn (stderr).

Vì vậy, 2>&1nói để gửi lỗi tiêu chuẩn đến nơi mà đầu ra tiêu chuẩn cũng đang được chuyển hướng. Mà vì nó được gửi đến /dev/nullgần giống như bỏ qua mọi đầu ra.


2
Có một lý do mà một dấu và xuất hiện trước 1, nhưng không phải trước 2? Tôi nghĩ rằng & là một nhân vật dành riêng để điều hành một công việc ở chế độ nền, nhưng tôi đoán đó chỉ là khi ký hiệu và xuất hiện dưới dạng một ký tự dài ở cuối lệnh ...?
Matt Huggins

8
Bởi vì 0(stdin), 1(stdout) và 2(stderr) thực sự là các mô tả tệp, shell yêu cầu một ký hiệu và đặt trước mặt chúng để chuyển hướng. Nó sao chép bộ mô tả tập tin trong trường hợp này hợp nhất hiệu quả hai luồng thông tin với nhau.
Chealion

12
Hãy nghĩ về nó theo cách này: nếu bạn chỉ có "1" mà không có dấu và, shell sẽ tạo một tệp có tên "1" và chuyển hướng đầu ra stderr sang nó.
CarlF

1
Được rồi, điều này một mình sẽ có giá trị? curl http://www.google.com 2>/dev/nullLàm thế nào để dòng lệnh biết rằng "2" ở đây có nghĩa là stderr và thực sự không phải là tham số thứ hai mà tôi chuyển đến lệnh curl?
Matt Huggins

1
@Matt Huggins: Vâng. Điều đó sẽ gửi tất cả đầu ra từ stderrthẳng đến /dev/nullthay thế. Bạn có thể thấy nó trong thực tế bằng cách thử curl, curl 1>/dev/nullcurl 2>/dev/nullchỉ để xem thay đổi đầu ra. Một lần nữa, ký hiệu chỉ cần thiết cho bộ mô tả tệp được chuyển hướng đến.
Chealion

23

tl; dr

Tìm nạp http://www.google.comtrong nền và loại bỏ cả stdoutstderr.

curl http://www.google.com > /dev/null 2>&1 &

giống như

curl http://www.google.com > /dev/null 2>/dev/null &

Khái niệm cơ bản

0, 12đại diện cho các tập tin tiêu chuẩn mô tả trong POSIX hệ điều hành. Một mô tả tệp là một tham chiếu hệ thống (về cơ bản) một tệp hoặc ổ cắm .

Tạo một bộ mô tả tệp mới trong C có thể trông giống như thế này:

fd = open("data.dat", O_RDONLY)

Hầu hết các lệnh hệ thống Unix lấy một số đầu vào và đầu ra kết quả đến thiết bị đầu cuối. curlsẽ tìm nạp bất cứ thứ gì có trong url được chỉ định ( google dot com ) và hiển thị kết quả stdout.

kết quả curl

Chuyển hướng

Giống như bạn đã nói <>được sử dụng để chuyển hướng đầu ra từ một lệnh đến một nơi khác, như một tệp.

Ví dụ: trong ls > myfiles.txt, lslấy nội dung của thư mục hiện tại và >chuyển hướng đầu ra của nó myfiles.txt(nếu tệp không tồn tại, nó được ghi đè, nhưng bạn có thể sử dụng >>thay vì >nối vào tệp thay thế). Nếu bạn chạy lệnh trên, bạn sẽ thấy không có gì được hiển thị cho thiết bị đầu cuối. Điều đó thường có nghĩa là thành công trong các hệ thống Unix. Để kiểm tra điều này cat myfiles.txtđể hiển thị nội dung tập tin ra màn hình.

> / dev / null 2> & 1

Phần đầu tiên > /dev/nullchuyển hướng stdout, đó là curlđầu ra của /dev/null(nhiều hơn về điều này phía trước) và 2>&1chuyển hướng stderrđến stdout(mà chỉ được chuyển hướng đến /dev/nullđể mọi thứ sẽ được gửi đến /dev/null).

Phía bên trái 2>&1cho bạn biết những gì sẽ được chuyển hướng, và bên phải cho bạn biết nơi để. Các &được sử dụng ở bên phải để phân biệt stdout (1)hoặc stderr (2)từ tập tin có tên 1hay 2. Vì vậy, 2>1cuối cùng sẽ tạo một tệp mới (nếu nó chưa tồn tại) được đặt tên 1stderrkết quả trong đó.

/ dev / null

/dev/nulllà một tập tin trống, một cơ chế được sử dụng để loại bỏ mọi thứ được ghi vào nó. Vì vậy, curl http://www.google.com > /dev/nullcó hiệu quả ngăn chặn curlđầu ra của.

> / dev / null

Nhưng tại sao có một số thứ vẫn được hiển thị trên thiết bị đầu cuối?. Đây không phải curl là đầu ra thông thường, nhưng dữ liệu được gửi tới stderr, được sử dụng ở đây để hiển thị thông tin chẩn đoán và tiến trình và không chỉ lỗi .

curl http://www.google.com > /dev/null 2>&1bỏ qua cả thông tin tiến độ curlvà đầu ra của cả hai curl. Kết quả là không có gì được hiển thị trên thiết bị đầu cuối.

Cuối cùng

Các &cuối cùng là cách bạn nói với vỏ để chạy các lệnh như một công việc trong nền . Điều này khiến cho dấu nhắc trở lại ngay lập tức trong khi lệnh được chạy không đồng bộ phía sau hậu trường. Để xem các loại công việc hiện tại jobstrong thiết bị đầu cuối của bạn. Lưu ý điều này khác với các quy trình đang chạy trong hệ thống của bạn. Để xem những loại toptrong thiết bị đầu cuối.

Người giới thiệu


1
Đây là một trong những câu trả lời tốt nhất trên toàn bộ trang web từ góc độ bố cục, được thực hiện tốt!
OmarOthman

Một điều tôi không nhận được là tại sao bạn muốn gửi mọi thứ đến /dev/null? Bạn không muốn kết quả của curlít nhất một nơi nào đó hữu ích?
skube

@skube Đúng rồi. Trong trường hợp này, tôi không rõ lý do tại sao người dùng muốn loại bỏ cả thiết bị xuất chuẩn và thiết bị xuất chuẩn. OP có lẽ chỉ muốn hiểu cú pháp nghĩa là gì.
Jorge Bucaran

5

2đề cập đến STDERR. 2>&1sẽ gửi STDERR đến cùng vị trí với 1(STDOUT).


0

Tôi hiểu như sau:

Nếu bạn chỉ muốn đọc thông tin Đầu ra và Lỗi của lệnh trên màn hình, thì chỉ cần viết: curl http://www.google.com

Và đôi khi bạn muốn lưu thông tin Đầu ra vào một tệp thay vì màn hình đầu cuối để xem lại sau, thì bạn có thể viết: curl http://www.google.com > logfile

Nhưng theo cách này, thông tin StdErr sẽ bị bỏ qua, vì >chỉ chuyển hướng StdOut sang logfile.

Vì vậy, nếu bạn quan tâm đến thông tin lỗi của lệnh một khi nó không thực thi, thì bạn cần kết hợp StdOut với StdErr bằng cách sử dụng 2>&1(có nghĩa là gấp StdErr thành StdOut), vì vậy dòng lệnh sau có thể được viết: curl http://www.google.com > logfile2> & 1

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.