sự khác biệt giữa `>> / dev / stderr` (với khoảng trắng) và`> & 2` là gì?


11

Trong bash.

Tôi đang gặp một số khó khăn để xác định những gì tôi nên sử dụng?

tất cả các tập lệnh của tôi sử dụng ">> / dev / stderr"

tại bash prompt, nếu tôi thử:
echo test >>/dev/stderrcông
echo test >> /dev/stderrtrình
echo test >/dev/stderrhoạt
echo test > /dev/stderrđộng công trình hoạt động

echo test >>&2FAILS!
echo test >> &2FAILS! FAILS
echo test >&2hoạt động
echo test > &2!

Tôi sẵn sàng thay đổi tất cả các kịch bản của tôi để >&2.

Nó dường như cũng có ảnh hưởng lớn đến ssh (sau su SomeUser) khi >>/dev/stderrhoàn toàn không hoạt động (quyền bị từ chối), chỉ >&2hoạt động.


bạn có thể đưa ra một ví dụ về lỗi ssh? Tôi không thể tái tạo nó.
Jeff Schaller

@JeffSchaller bạn đúng, Chỉ sau khi susự cố xảy ra, hãy cập nhật câu hỏi
Sức mạnh của Bảo Bình

@AquariusPower, ... để giải thích sự khác biệt đó, nhân tiện: với su -c 'some command'lệnh đó được điều hành bởi /bin/sh, không bash, vì vậy, hành vi cụ thể của bash (như mô phỏng /dev/stderrcho mục đích chuyển hướng khi không khả dụng) không được đảm bảo có mặt.
Charles Duffy

Câu trả lời:


22

>& nlà cú pháp shell để sao chép trực tiếp một bộ mô tả tập tin . Mô tả tập tin 2 là stderr; đó là cách người ta làm việc Bạn cũng có thể sao chép các mô tả tệp khác, không chỉ stderr. Bạn không thể sử dụng chế độ chắp thêm ở đây vì sao chép bộ mô tả tệp không bao giờ cắt ngắn (ngay cả khi thiết bị lỗi của bạn là tệp) và >&là một mã thông báo, đó là lý do tại sao bạn không thể đặt một khoảng trắng bên trong nó nhưng vẫn >& 2hoạt động.

>> namelà một cú pháp được phép khác nhau, trong đó nametên tệp (và mã thông báo là >>). Trong trường hợp này, bạn đang sử dụng tên tệp /dev/stderr, do xử lý dành riêng cho hệ điều hành (trên Linux, đó là một liên kết tượng trưng /proc/self/fd/2) cũng có nghĩa là lỗi tiêu chuẩn. Nối và cắt chế độ cả hai kết thúc làm cùng một việc khi thiết bị đầu cuối là thiết bị đầu cuối vì không thể cắt ngắn. Tuy nhiên, nếu lỗi tiêu chuẩn của bạn là một tệp, nó sẽ bị cắt ngắn:

anthony@Zia:~$ bash -c 'echo hi >/dev/stderr; echo bye >/dev/stderr' 2>/tmp/foo
anthony@Zia:~$ cat /tmp/foo
bye

Nếu bạn thấy lỗi với /dev/stderrhơn ssh, có thể quản trị viên máy chủ đã áp dụng một số biện pháp bảo mật ngăn chặn liên kết tượng trưng đó hoạt động. (Ví dụ: bạn không thể truy cập /prochoặc /dev). Mặc dù tôi hy vọng sẽ gây ra tất cả các loại phá vỡ kỳ lạ, sử dụng cú pháp mô tả tệp trùng lặp là một cách tiếp cận hoàn toàn hợp lý (và có thể hiệu quả hơn một chút). Cá nhân tôi thích nó.


Tôi đã gặp một rắc rối lớn khi cố gắng tái tạo vấn đề cắt ngắn mà tôi gặp phải trước đây (nếu không tôi sẽ thêm nó vào câu hỏi hehe), lý do tôi thay đổi mọi thứ để sử dụng >>, vì đã chỉ ra điều đó! Ngoài ra, tôi đã bỏ lỡ một bước su SomeUsersau khi kết nối thông qua ssh.
Sức mạnh Bảo Bình

Điều này bash -c 'echo hi >&2; echo bye >&2' 2>/tmp/foo;cat /tmp/foosẽ không cắt ngắn tho! (ngay cả với 2>&1 |tee /tmp/foo) những gì là hoàn hảo để đăng nhập và sẽ hoạt động hoàn hảo sau khi tôi thay đổi tất cả thành >&2. Vì vậy, tôi đoán chỉ sử dụng tệp trực tiếp /dev/stderrcho phép cắt ngắn, không phải mô tả trùng lặp, mát mẻ thx!
Sức mạnh Bảo Bình

@AquariusPower chính xác, mô tả tập tin trùng lặp không bao giờ cắt ngắn. Đó là trong đoạn đầu tiên, có lẽ tôi cần làm nổi bật nó bằng cách nào đó?
derobert

không cần thiết, đôi khi tôi chậm chạp
Sức mạnh của Bảo Bình

3
Câu trả lời này có thể được cải thiện. > & là một mã thông báo không phải hai và có sự nhầm lẫn của OP.
Joshua

8

Các trường hợp thất bại xảy ra do cú pháp bash để sử dụng &trong các chuyển hướng chỉ định một lần duy nhất >và yêu cầu nó tồn tại trực tiếp liền kề với &dấu hiệu:

[n]> & từ


2

Sử dụng '>'để chuyển hướng (cắt ngắn nếu tồn tại) hoặc '>>'(nối thêm nếu tồn tại).

'>&'Ví dụ, sử dụng để nhân đôi một luồng, nếu bạn muốn đầu ra tiêu chuẩn VÀ lỗi tiêu chuẩn trong cùng một tệp, bạn chuyển hướng đến tệp '> output.log'và cũng có lỗi với'2>&'

myjob.sh > output.log 2>&
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.