Làm thế nào tôi có thể nhớ làm thế nào để sử dụng chuyển hướng?


40

Tôi biết những gì

  program > /dev/null 2>&1 

làm. Nó chuyển hướng đầu ra /dev/null2>&1có nghĩa là chuyển hướng đầu ra lỗi ở cùng một nơi mà đầu ra được gửi.

Vấn đề của tôi là tôi luôn phải google nó bởi vì tôi không bao giờ nhớ nó.

Vì vậy, tôi cố gắng &2>1, 1>2&, 1>&2... Tôi thử mọi sự kết hợp cho đến khi tôi google nó ...

Bí quyết để nhớ nó dễ dàng là gì?


Tôi có cùng một vấn đề, vì vậy tôi thực hiện theo cách "dài" - chuyển hướng cả hai program 1> /dev/null 2>/dev/null. Đôi khi, mặc dù bạn cần phải trộn lẫn stdoutstderrcùng nhau để xem điều gì đang thực sự xảy ra - như đầu ra từ một quá trình biên dịch phức tạp đang được chuyển hướng đến một tệp. Trong trường hợp đó, tôi kết thúc việc này
ivanivan

Câu trả lời:


20

Đầu ra tốt hơn lỗi nên xuất hiện trước (1 so với 2).

>là viết tắt của 'đi đến'. Bên trái là những gì tôi muốn gửi và bên phải là nơi tôi muốn gửi nó. Vì 'where' luôn luôn là một tập tin, đại loại như

program > /dev/null 2>1

sẽ chuyển hướng đến một tệp có tên 1. Do đó, ký hiệu và (&)sửa đổi tệp thành mô tả tệp.

Thật không may, tôi đã không bắt gặp và cũng không phát triển khả năng ghi nhớ của riêng mình, nhưng khi tôi mới học * nix, tôi đã tìm thấy cách hợp lý này để hoạt động tốt. Sau một vài lần chạy qua, nó trở thành bản chất thứ hai.


Câu đầu tiên của bạn không có ý nghĩa với tôi. stdoutlà mô tả tập tin 1, stderrlà 2. Vì vậy, "lỗi" xuất hiện trước "đầu ra".
Warren Young

Câu đó là một ghi nhớ để nhớ mô tả tập tin stdoutstderrtham chiếu.
gvkv

Được rồi, nhưng nó vẫn có vẻ khó hiểu, vì câu hỏi ban đầu là về việc cố gắng nhớ thứ tự của các ký tự trong câu thần chú "2> & 1".
Warren Young

9

Một mẹo nhỏ là chỉ cần nhớ rằng 1 = đầu ra tiêu chuẩn, 2 = lỗi tiêu chuẩn. Vì thế:

2>&1= luồng lỗi tiêu chuẩn đi vào luồng đầu ra tiêu chuẩn.
1>&2= ngược lại.

Nếu bạn đã từng lập trình bằng ngôn ngữ giống như C, thật dễ dàng để nhớ ký hiệu và ( &). Tôi chọn nghĩ về nó như đề cập đến "địa chỉ" của bộ mô tả tệp hiện có, để bạn không thay đổi tệp hoặc tạo một tệp mới.


7

Xem nút &như một nút thắt có thể giúp ích: suy nghĩ về những gì bạn muốn làm khi lấy đầu ra của 2, vì vậy 2>, và buộc nó cùng với 1, vì vậy2>&1


2
Tôi chỉ ghi nhớ cụm từ "hai ra và một". Cho dù ghi nhớ của bạn là một cụm từ hoặc một nút thắt, có một cái sẽ thực sự có ích.
Tim Kennedy

5

Trên thực tế, nó phụ thuộc vào loại vỏ bạn đang sử dụng. Bash thường rất tha thứ và bạn chỉ có thể làm:

program &> file

5

Chúng ta hãy xem xét ba lựa chọn sau:

program  2>1
program  2>1& 
program  2>&1

Đầu tiên gửi stderr đến một tên tệp "1": sau tất cả, bash mong muốn chuyển hướng đến một tệp.

Cái thứ hai cũng chuyển hướng đến cùng một tệp nhưng chạy programtrong nền: đó là ý nghĩa của một dấu vết &.

Điều đó để lại khả năng thứ ba là khả năng duy nhất có ý nghĩa trong vũ trụ bash để chuyển hướng đến một tệp xử lý.

Làm thế nào để nhớ cái nào trong số 0, 1, 2? Hãy suy nghĩ về việc chạy một máy tính từ bàn điều khiển. Đầu tiên, bạn phải gõ một cái gì đó (0 = stdin). Sau đó, bạn thấy đầu ra (1 = thiết bị xuất chuẩn). Cuối cùng và chỉ khi có sự cố xảy ra, bạn sẽ thấy stderr (2).


1

Vẽ nó trong hình nền của bạn.

Bây giờ, nghiêm túc, điều này và những thứ cơ bản khác mà tôi đã quên, vì vậy tôi đã thêm một menu mẹo nhanh vào một ứng dụng tôi đã phát triển và tôi sử dụng hàng ngày. Bạn có thể muốn dùng thử hoặc sử dụng một cái gì đó như chú thích để ghi chú.


1

Liên quan đến bash shell, tôi thấy cách tốt nhất để nhớ là bằng cách hiểu những gì đang xảy ra.
Nếu tất cả những gì bạn muốn làm là nhớ cách lấy lệnh chính xác, bạn có thể thử

program > /results 2> /results

Đó là những gì tốt đẹp và rõ ràng đang diễn ra và dễ nhớ. I E

  • 1 STDOUT sẽ /results
  • 2STDERR cũng sẽ trực tiếp đến/results

vấn đề là điều này không hoạt động như bạn mong đợi. xem xét những điều sau đây

tập tin: /tmp/poem.txt

the quick brown fox jumped over the lazy dog

và lệnh chạy

grep "brown" /tmp/poem.txt NOT_A_FILE > /tmp/results 2> /tmp/results

sau đó

$ cat /tmp/results
grep: NOT_A_FILE: No such file or directory
 lazy dog

chuyện gì đã xảy ra ở đây
Sự hiểu biết của tôi là bash thiết lập chuyển hướng trỏ STDERR trực tiếp vào tệp /tmp/resultsvà vì bản chất của >nó làm 2 việc

  1. thường tạo một tệp mới - trong trường hợp này cơ hội đã qua vì bash đã vượt qua thói quen này tại thời điểm đầu ra được tạo.
  2. chèn thẳng vào phần đầu của tập tin và không nối như >>không.

Vì vậy, trong trường hợp này STDERR, chèn trực tiếp vào phần đầu ghi /tmp/resultsđè đầu ra của STDOUT.
Lưu ý: nếu bạn đã sử dụng >>để nối thêm, bạn có thể thoát khỏi cú pháp này.
Tuy nhiên, để khắc phục sự cố bạn cần - không phải chuyển hướng STDERR - trực tiếp đến tệp, mà là để hợp nhất đầu ra của STDERR vào luồng STDOUT, do đó bạn không bị xung đột.
Sử dụng toán 2>&1tử toán tử đạt được điều này

grep "brown" poem.txt NOT_A_FILE > /tmp/results 2>&1

Các &phép bash để phân biệt từ một file có tên 11mô tả tập tin.
Đối với tôi, bản 2>&1thân câu lệnh giải thích chính xác những gì đang xảy ra - STDERR đang được chuyển hướng tại chính STDOUT - và chỉ kết thúc ở đó /tmp/resultsvì đó là điểm mà STDOUT được chỉ ra (gần như là một tác dụng phụ).
Trái ngược với những gì rất nhiều hướng dẫn yêu cầu, đó là 2>&1gửi STDERR đến nơi mà STDOUT được chỉ. Nếu đó là sự thật - bạn vẫn sẽ gặp vấn đề về ghi đè.

Để biết thêm thông tin, hãy xem - http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection

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.