Tôi không nghĩ rằng đây hoàn toàn là một vấn đề bash.
Trong một bình luận, bạn nói rằng bạn đã thấy lỗi này sau khi thực hiện
sudo su username2
khi đăng nhập như username
. Đó là su
điều gây ra vấn đề.
/dev/stdout
là một liên kết tượng trưng /proc/self/fd/1
, ví dụ như một liên kết tượng trưng /dev/pts/1
. /dev/pts/1
, đó là một giả hành, được sở hữu bởi, và có thể ghi bởi username
; quyền sở hữu đó đã được cấp khi username
đăng nhập. Khi bạn sudo su username2
, quyền sở hữu /dev/pts/1
không thay đổi và username2
không có quyền viết.
Tôi cho rằng đây là một lỗi. /dev/stdout
nên được, trên thực tế, một bí danh cho dòng đầu ra tiêu chuẩn, nhưng ở đây chúng ta thấy một tình huống mà echo hello
các công trình nhưng echo hello > /dev/stdout
thất bại.
Một cách giải quyết khác là tạo username2
thành viên của nhóm tty
, nhưng điều đó sẽ cho username2
phép viết cho bất kỳ tty nào , điều này có thể là không mong muốn.
Một cách giải quyết khác là đăng nhập vào username2
tài khoản thay vì sử dụng su
, để /dev/stdout
chỉ ra một giả hành mới được phân bổ thuộc sở hữu của username2
. Điều này có thể không thực tế.
Một cách giải quyết khác là sửa đổi tập lệnh của bạn để chúng không tham chiếu /dev/stdout
và /dev/stderr
; ví dụ: thay thế cái này:
echo OUT > /dev/stdout
echo ERR > /dev/stderr
bằng cách này
echo OUT
echo ERR 1>&2
Tôi thấy điều này trên hệ thống của riêng tôi, Ubuntu 12.04, với bash 4.2.24 - mặc dù tài liệu bash ( info bash
) trên hệ thống của tôi nói điều đó /dev/stdout
và /dev/stderr
được xử lý đặc biệt khi được sử dụng trong các chuyển hướng. Nhưng ngay cả khi bash không xử lý các tên đó một cách đặc biệt, chúng vẫn nên đóng vai trò tương đương cho các luồng I / O tiêu chuẩn. (POSIX không đề cập đến /dev/std{in,out,err}
, vì vậy có thể khó tranh luận rằng đây là một lỗi.)
Nhìn vào các phiên bản cũ của bash, tài liệu ngụ ý rằng /dev/stdout
et al được xử lý đặc biệt cho dù các tệp có tồn tại hay không. Tính năng này được giới thiệu trong bash 2.04 và NEWS
tệp cho phiên bản đó cho biết:
Mã chuyển hướng hiện xử lý một số tên tệp đặc biệt: / dev / fd / N, / dev / stdin, / dev / stdout và / dev / stderr, cho dù chúng có trong hệ thống tệp hay không.
Nhưng nếu bạn kiểm tra mã nguồn ( redir.c
), bạn sẽ thấy rằng xử lý đặc biệt chỉ được bật nếu biểu tượng HAVE_DEV_STDIN
được xác định (điều này được xác định khi bash được xây dựng từ nguồn).
Theo như tôi có thể nói, không có phiên bản bash nào được phát hành đã khiến việc xử lý đặc biệt của /dev/stdout
et al trở nên vô điều kiện - trừ khi một số bản phân phối đã vá nó.
Vì vậy, một cách giải quyết khác (mà tôi chưa thử) sẽ là lấy các nguồn bash , sửa đổi redir.c
để /dev/*
xử lý đặc biệt vô điều kiện và sử dụng phiên bản được xây dựng lại của bạn thay vì phiên bản đi kèm với hệ thống của bạn. Điều này có lẽ là quá mức cần thiết, mặc dù.
TÓM LƯỢC :
Hệ điều hành của bạn, giống như của tôi, không xử lý quyền sở hữu và quyền /dev/stdout
và /dev/stderr
chính xác. bash được cho là xử lý các tên này đặc biệt trong các chuyển hướng, nhưng thực tế nó chỉ làm như vậy nếu các tệp không tồn tại. Điều đó sẽ không quan trọng nếu /dev/stdout
và /dev/stderr
làm việc chính xác. Vấn đề này chỉ hiển thị khi bạn su
đến một tài khoản khác hoặc làm điều gì đó tương tự; nếu bạn chỉ cần đăng nhập vào một tài khoản, các quyền là chính xác.
ls -l /dev/stdout /dev/stderr
và làls -lL /dev/stdout /dev/stderr
gì?