Bash nào viết dòng nhắc của nó tới?


8

Tôi đang cố gắng chuyển hướng tất cả đầu ra từ bash (dấu nhắc, đầu vào của người dùng, kết quả) sang một tệp

Thí dụ:

/bin/bash > file.txt 2>&1

Tôi nghĩ rằng nó sẽ làm việc, nhưng tôi không nhận được lời nhắc. Bất cứ ai có thể cho tôi biết những gì tôi đang làm sai?

Câu trả lời:


9

Bash chỉ đưa ra lời nhắc trong chế độ tương tác. Tức là nó thường xuất ra terminal (/ dev / tty trên linux). Đó không phải là / dev / stdout hoặc / dev / stdin :)

Bây giờ, tôi không chắc nhưng tôi có thể tưởng tượng rằng bash sẽ cho phép chế độ tương tác hạn chế khi không có tty đầy đủ chức năng. Trong trường hợp đó, tôi hy vọng lời nhắc sẽ được ghi vào thiết bị xuất chuẩn. Tôi đã không kiểm tra điều đó.

Bằng chứng tốt đẹp về khái niệm:

(for a in some set of words; do echo $a > /dev/tty; done) 2>&1 > /dev/null

sẽ chỉ xuất 1..10 như thể không có chuyển hướng. Giống như lời nhắc, đầu ra được gửi trực tiếp đến thiết bị đầu cuối (sẽ không thành công nếu không có)

GỢI Ý: nếu bạn muốn mọi thứ được thu thập hãy nhìn vào


Đã thêm gợi ý về cách có khả năng nhận được nhiều đầu ra bash hơn vào đường ống
sehe

seqlà một lệnh bên ngoài không chuẩn, và không nên được sử dụng theo cách này. Nếu bạn đang sử dụng bash, hãy làm một cái gì đó nhưfor x in {1..10} , hoặc for ((x=1; x<=10; x++))thay vào đó.
Chris Xuống

@Chris: điểm tốt, cảm ơn vì đã ngẩng cao đầu
sehe

2

Để đánh lừa bashsuy nghĩ về chế độ tương tác (mặc dù stdoutkhông được gửi đến thiết bị đầu cuối), bạn có thể sử dụng lệnh đã được đề cập script.

(
exec 1> >(tee bashlog.txt) 2>&1
script -q /dev/null /bin/bash -l
)

# alternative without script command
(
# bash: no job control in this shell
exec 1> >(tee bashlog.txt) 2>&1
/bin/bash -il
)

2

Lời nhắc được viết cho stderr như giàn (trên Solaris tại đây) hiển thị:

$ truss -ft write -p 10501
10501:  write(2, " d", 1)               = 1
10501:  write(2, " a", 1)               = 1
10501:  write(2, " t", 1)               = 1
10501:  write(2, " e", 1)               = 1
10501:  write(2, "\n", 1)               = 1
10521:  write(1, " S a t u r d a y ,   S e".., 46)  = 46
10501:      Received signal #18, SIGCLD [caught]
10501:        siginfo: SIGCLD CLD_EXITED pid=10521 status=0x0000
10501:  write(2, " $  ", 2)             = 2

1

Cách đơn giản nhất để làm điều đó là

bash -i >/tmp/logfile 2>&1

Bash sẽ viết mọi thứ /tmp/logfilevà tiếp tục thực thi các lệnh khi bạn gõ chúng, nhưng không có gì sẽ được hiển thị trong terminal. Bạn có thể làm cho nó thoát giống như bạn thoát khỏi phiên cuối của mình - bằng cách nhấnCtrl + Dhoặc gõ exit.

Lưu ý rằng nếu bạn chạy cùng một thứ mà không có stderr chuyển hướng, bạn sẽ chỉ có thông điệp chúc mừng được ghi vào tệp, tất cả phần còn lại sẽ hoạt động trong thiết bị đầu cuối hiện tại của bạn. Vì vậy, câu trả lời cho câu hỏi của bạn về luồng mà bash đưa ra dấu nhắc của nó (và tất cả các lệnh sau) dường như là: stderr .

Ồ vâng, và -itham số chỉ đơn giản là buộc bash chạy trong chế độ tương tác. Đừng nghe những người đó - bạn không cần bất kỳ trò ảo thuật nào để làm điều đó;)


+1 để sử dụng <sub>để định dạng. Tôi vừa học được một cái gì đó mới ngày hôm nay. : D
Chris K
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.