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>&1
trong dòng lệnh. Ví dụ:
curl http://www.google.com > /dev/null 2>&1 &
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>&1
trong dòng lệnh. Ví dụ:
curl http://www.google.com > /dev/null 2>&1 &
Câu trả lời:
Các 1
biểu thị đầu ra tiêu chuẩn (stdout). Các 2
biểu thị lỗi tiêu chuẩn (stderr).
Vì vậy, 2>&1
nó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/null
gần giống như bỏ qua mọi đầu ra.
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.
curl http://www.google.com 2>/dev/null
Là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?
stderr
thẳng đến /dev/null
thay thế. Bạn có thể thấy nó trong thực tế bằng cách thử curl
, curl 1>/dev/null
và curl 2>/dev/null
chỉ để 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.
Tìm nạp http://www.google.com
trong nền và loại bỏ cả stdout
và stderr
.
curl http://www.google.com > /dev/null 2>&1 &
giống như
curl http://www.google.com > /dev/null 2>/dev/null &
0
, 1
Và 2
đạ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. curl
sẽ 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
.
Giống như bạn đã nói <
và >
đượ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
, ls
lấ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.
Phần đầu tiên > /dev/null
chuyể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>&1
chuyể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>&1
cho 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 1
hay 2
. Vì vậy, 2>1
cuố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 1
và stderr
kết quả trong đó.
/dev/null
là 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/null
có hiệu quả ngăn chặn curl
đầu ra của.
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>&1
bỏ qua cả thông tin tiến độ curl
và đầ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.
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 jobs
trong 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 top
trong thiết bị đầu cuối.
/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?
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 > logfile
2> & 1