Sự khác biệt giữa &> và 2> & 1 là gì


30

Có hai hình thức chuyển hướng đầu ra tiêu chuẩnlỗi tiêu chuẩn thành đầu ra tiêu chuẩn . Nhưng cái nào thì tốt hơn? và tại sao &>được coi là hoàn hảo?

Tôi không thể tìm thấy sự khác biệt là gì để nhiều hướng dẫn và thậm chí bash trạng thái thủ công &>là tốt hơn!

Vậy tại sao tôi nên sử dụng &>và không2>&1

Chủ yếu sử dụng bashvỏ


EDIT: Cảm ơn các bình luận viên

Chỉ> & hoạt động trong csh hoặc tcsh

Trong ksh chỉ có 2> & 1 hoạt động.

chỉ sử dụng dấu gạch ngang> tệp 2> & 1 chuyển hướng

Sau đó, sử dụng cái nào để đảm bảo tập lệnh của tôi tương thích với các hệ thống khác bất kể shell được sử dụng là gì!


tốt hơn là những gì bạn cần làm. những điều này làm những điều rất khác nhau. bạn đang sử dụng vỏ nào?
Skaperen

@Skaperen sử dụng bash
Maythux

1
điều gì làm bạn muốn đạt được?
Skaperen

Tôi chỉ muốn biết sự khác biệt là gì, Những gì tôi muốn dont là trong cả hai nhưng tôi chỉ cần biết nếu là một sự khác biệt để một lần được preffred trên khác
Maythux

2
&> somewherechỉ là viết tắt bash cho > somewhere 2>&1: theo cách nói của hướng dẫn sử dụng bash, chúng là "tương đương về mặt tương đối"
Steeldo

Câu trả lời:


23

Trang người đàn ông của Bash đề cập đến có hai cách để chuyển hướng stderr và stdout : &> file>& file. Bây giờ, lưu ý rằng nó nói cả stderr và stdout.

Trong trường hợp này, >file 2>&1chúng tôi đang chuyển hướng thiết bị xuất chuẩn (1) sang tệp, nhưng sau đó cũng báo cho thiết bị xuất chuẩn (2) được chuyển hướng đến cùng một vị trí như thiết bị xuất chuẩn! Vì vậy, mục đích có thể giống nhau, nhưng ý tưởng hơi khác nhau. Nói cách khác "John, đi học; Suzzie đi nơi John đi".

Còn sở thích thì sao? &>là một bashđiều Vì vậy, nếu bạn đang chuyển một kịch bản, điều đó sẽ không làm điều đó. Nhưng nếu bạn chắc chắn 100%, tập lệnh của bạn sẽ chỉ hoạt động trên hệ thống với bash - thì không có ưu tiên nào

Đây là một ví dụ với dash, Debian Amquist Shell là mặc định của Ubuntu.

$ grep "YOLO" * &> /dev/null
$ grep: Desktop: Is a directory
grep: Documents: Is a directory
grep: Downloads: Is a directory
grep: Music: Is a directory
grep: Pictures: Is a directory
grep: Public: Is a directory
grep: Templates: Is a directory
grep: Videos: Is a directory
grep: YOLO: Is a directory
grep: bin: Is a directory

Như bạn có thể thấy, stderr không được chuyển hướng

Để giải quyết các chỉnh sửa của bạn trong câu hỏi, bạn có thể sử dụng câu lệnh if để kiểm tra biến $ SHELL và thay đổi chuyển hướng tương ứng

Nhưng đối với hầu hết các trường hợp > file 2>&1nên làm việc


Theo thuật ngữ kỹ thuật hơn, biểu mẫu [integer]>&wordđược gọi là Bộ mô tả tệp đầu ra trùng lặp và là một tính năng được chỉ định bởi tiêu chuẩn Ngôn ngữ lệnh Shell POSIX, được hỗ trợ bởi hầu hết các trình bao tương tự POSIX và giống như Brourne.

Xem thêm Điều gì có nghĩa là & chính xác trong chuyển hướng đầu ra?


Sau đó, những gì xảy ra khi sử dụng trên một số vỏ khác?
Maythux

zsh hỗ trợ &>.... @Maythux Trong các shell không hỗ trợ, &>ví dụ: dashbạn cần sử dụng >file 2>&1chuyển hướng tầm thường ..
heemayl

Sau đó, nên sử dụng cái nào nếu tôi muốn chắc chắn rằng tập lệnh của tôi sẽ tương thích với các shell khác nhau
Maythux

3
@Maythux Sử dụng >file 2>&1. Công việc này trên tất cả các vỏ
Sergiy Kolodyazhnyy

1
Các vỏ @ TSJNachos117 được đặt /etc/passwdcho mỗi người dùng là các vỏ tương tác. Các kịch bản hệ thống thường được sử dụng dash trừ khi có quy định khác. Đối với những gì được mặc định, nó được xác định bởi những gì được liên kết với /bin/shtrường hợp của Ubuntu dash. Trong RHEL, đó là bash, trong FreeBSD, nó là tcsh nguồnmột nguồn khác
Sergiy Kolodyazhnyy

6

Nói chung, tôi khuyên bạn nên làm theo cách làm của Bourne một lần nữa , vì bash được cho là vỏ Unix phổ biến nhất hiện có. Bash thường sử dụng &>hoặc 2>&1. IMHO, không phải là "hoàn hảo", vì vậy tôi khuyên bạn nên quên đi điều vô nghĩa đó. Trên thực tế, cái nào bạn nên sử dụng phụ thuộc vào những gì bạn đang cố gắng làm.

2>&1hợp nhất stderr với thiết bị xuất chuẩn, có thể hữu ích nếu, ví dụ, bạn muốn chuyển văn bản stderr. Vì vậy, ví dụ, nếu bạn muốn xem chương trình có in một thông điệp stderr nào đó không, nhưng không muốn màn hình của bạn chứa đầy rác không quan trọng, có thể bạn sẽ làm gì đó như program 2>&1 | grep crashedtìm kiếm thiết bị xuất chuẩn và thiết bị xuất chuẩn từ chương trình gọi là "chương trình" cho từ "sụp đổ".

Mặt khác, nếu bạn không muốn một chương trình in bất cứ thứ gì, bạn có thể chỉ cần chạy program &> /dev/null, nó sẽ chuyển hướng cả stderr và stdout sang / dev / null, một tệp đặc biệt làm cho mọi thứ biến mất một cách kỳ diệu. Hoặc, nếu bạn muốn lưu kết quả của chương trình (có thể báo cáo lỗi hoặc lỗi gì đó), bạn có thể chuyển hướng cả stderr và stdout sang tệp: program &> log.txtsẽ chuyển hướng tất cả dữ liệu sang tệp có tên là "log.txt". Nếu bạn muốn, bạn có thể chuyển hướng thiết bị xuất chuẩn và thiết bị xuất chuẩn thông qua program 2> log.txt > log.txthoặc program 2>&1 | cat > log.txt, cả hai đều có tác dụng tương tự như khi sử dụng &>. Nếu bạn làm một cái gì đó như thế program 2>&1 > file, chỉ có thiết bị xuất chuẩn sẽ được chuyển hướng, nhưng thiết bị xuất chuẩn vẫn có thể được dẫn đến một chương trình khác, chẳng hạn như con mèo, có thể được chuyển hướng như được hiển thị ở trên. Tuy nhiên, gõ&>dễ dàng hơn bất kỳ ví dụ nào ở trên, vì nó liên quan đến việc nhập ít ký tự hơn (và con người dễ đọc hơn một chút). Hãy lưu ý rằng program 2> log.txt > log.txtcó thể có nhiều khả năng hoạt động trên các vỏ không bash.

Tái bút: nếu bạn lo lắng về việc mọi người sử dụng các shell khác, có một thứ bạn có thể thêm vào là dòng đầu tiên của tập lệnh của bạn được gọi là "số ma thuật" hoặc "shebang". Đây thực chất là một cách để đảm bảo các máy tính khác (đặc biệt là các máy tính chạy hệ điều hành giống Unix) biết nên sử dụng chương trình nào để thực thi tập lệnh. Các kịch bản khác nhau sử dụng các shebang khác nhau. Một shebang cho một kịch bản bash trông như thế này:

#!/bin/bash

Nếu bạn sử dụng ở trên làm dòng đầu tiên của một tập lệnh đã cho, bash thường sẽ được sử dụng để thực thi tập lệnh đã nói. Điều này sẽ khiến việc ai đó vô tình thực thi tập lệnh với shell sai sẽ khó khăn hơn nhiều.

Tái bút: Tôi sẽ không nói dối: cho đến bây giờ, tôi không biết người ta có thể sử dụng >&, nhưng, theo như bash, nó dường như làm như vậy &>. Bạn học được điều gì mới mỗi ngày.


Mặc dù tôi đồng ý với bạn về việc sử dụng #!dòng để yêu cầu rõ ràng bash, nhưng nó không phải lúc nào cũng có sẵn trên các hệ thống khác. Rất thường các nhà phát triển / sysadins phải viết các tập lệnh di động cho các hệ thống bashcó thể không khả dụng và nó có thể không thuộc quyền kiểm soát của họ để cài đặt bash. Đây >file 2>&1chỉ là nhiều di động.
Sergiy Kolodyazhnyy

Bạn đã thực hiện một lỗi đảo ngược ở trên, không tạo ra kết quả mà bạn yêu cầu hoặc muốn. Chuyển hướng stderr sang stdout, sau đó chuyển hướng stdout rời stderr trên stdout ban đầu.
ubfan1

Serg: Tôi không có ý ám chỉ bash là phổ quát. Tuy nhiên, tôi nghĩ nhiều người đang sử dụng nó hơn là nói (t) csh. Nếu bạn không biết người khác đang sử dụng cái gì và phải đoán mù, bash có lẽ là lựa chọn tốt nhất của bạn. Ngoài ra, tôi thường không biết về tính di động, vì tôi chỉ sử dụng bash. Thực tế >file 2>&1là nhiều di động là tốt để biết. Tôi sẽ thực hiện một chỉnh sửa để phản ánh điều đó.
TSJNachos117

Ubfan1, cảm ơn thông tin. Tôi sẽ không bao giờ đoán được trong một triệu năm rằng bash sẽ không chuyển hướng stderr đến một tập tin trong trường hợp đó. Tôi vừa chỉnh sửa câu trả lời của mình để ngăn người khác mắc lỗi tương tự.
TSJNachos117

4

Từ tài liệu tham khảo Bash -> 3.6.4 Chuyển hướng đầu ra tiêu chuẩn và lỗi tiêu chuẩn :

Cấu trúc này cho phép cả đầu ra tiêu chuẩn (mô tả tệp 1) và đầu ra lỗi tiêu chuẩn (mô tả tệp 2) được chuyển hướng đến tệp có tên là sự mở rộng của từ.

Có hai định dạng để chuyển hướng đầu ra tiêu chuẩn và lỗi tiêu chuẩn:

&>word

>&word

Trong hai hình thức, đầu tiên được ưa thích. Điều này tương đương với ngữ nghĩa

>word 2>&1

Khi sử dụng mẫu thứ hai, từ có thể không mở rộng thành số hoặc '-'. Nếu có, các toán tử chuyển hướng khác sẽ áp dụng (xem Sao chép tệp mô tả bên dưới) để biết lý do tương thích.

Cũng tốt khi tham khảo wiki của Greg về Đầu vào và Đầu ra -> 4.2. Thao tác mô tả tệp :

Để thuận tiện, Bash cũng cung cấp cho bạn một hình thức chuyển hướng khác. Toán tử &> chuyển hướng thực sự chỉ là một phiên bản ngắn hơn của những gì chúng tôi đã làm ở đây [ 2>&1]; chuyển hướng cả stdout và stderr vào một tập tin.


4

Vậy tại sao tôi nên sử dụng &> chứ không phải 2> & 1

2>&1 là vỏ Bourne / POSIX tiêu chuẩn.

&>là một phần mở rộng bash và không phải là tiêu chuẩn de jure .

Nếu bạn viết các tập lệnh bằng cách sử dụng các tiện ích mở rộng bash, sớm muộn bạn sẽ gặp phải các lỗi không thành công với các thông báo lỗi cú pháp khó hiểu vì chúng đang được chạy trong một vỏ tiêu chuẩn.

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.