Làm thế nào để xuất ra màn hình ghi đè chuyển hướng


8

Có thể, trong một tập lệnh shell, ghi vào màn hình trong khi STDOUT và STDERR đang được chuyển hướng?

Tôi có một tập lệnh shell mà tôi muốn chụp STDOUT và STDERR. Kịch bản sẽ chạy trong khoảng một giờ hoặc hơn, vì vậy tôi thỉnh thoảng muốn viết một số thông báo trạng thái lên màn hình sẽ được hiển thị và không được chuyển hướng (không được chụp).

Để có một ví dụ tối thiểu, tôi có một tập lệnh shell, hãy nói "./myscript.sh":

#!/bin/sh -u

echo "Message A: This writes to STDOUT or wherever '1>' redirects to."
echo "Message B: This writes to STDOUT or wherever '1>' redirects to.">&1
echo "Message C: This writes to STDERR or wherever '2>' redirects to.">/dev/stderr
echo "Message D: This writes to STDERR or wherever '2>' redirects to.">&2
echo "Message E: Write this to 'screen' regardless of (overriding) redirection." #>???  


Sau đó, ví dụ, tôi muốn xem đầu ra này khi tôi chạy tập lệnh như thế này:

[~]# ./myscript.sh > fileout 2> filerr
Message E: Write this to 'screen' regardless of (overriding) redirection.
[~]# ./myscript.sh > /dev/null 2>&1
Message E: Write this to 'screen' regardless of (overriding) redirection.
[~]#    


Nếu điều này không thể được thực hiện "trực tiếp", có thể tạm thời ngừng chuyển hướng, sau đó in một cái gì đó ra màn hình, sau đó khôi phục chuyển hướng như cũ không?

Một số thông tin về máy tính:

[~]# uname -srvmpio
Linux 3.2.45 #4 SMP Wed May 15 19:43:53 CDT 2013 x86_64 x86_64 x86_64 GNU/Linux

[~]# ls -l /bin/sh /dev/stdout /dev/stderr
lrwxrwxrwx 1 root root  4 Jul 18 23:18 /bin/sh -> bash
lrwxrwxrwx 1 root root 15 Jun 29  2013 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun 29  2013 /dev/stdout -> /proc/self/fd/1

1
echo msg > /dev/tty
Stéphane Chazelas

@strugee - Tôi muốn gắn thẻ nó với HĐH: "GNU / Linux" nhưng tôi không được phép (tôi thậm chí đã thử "GNU-Linux"), vì vậy tôi đã gắn thẻ riêng lẻ là "GNU" và "Linux".
Kevin Fegan

@StephaneChazelas - echo msg > /dev/tty. Điều đó đã làm việc! Tôi chắc chắn rằng tôi đã thử điều này sớm mà không thành công nhưng tôi phải thử những thứ tương tự khác. Trong mọi trường hợp, nó làm việc cho tôi. Nếu bạn muốn đặt câu hỏi này làm câu trả lời, tôi sẽ đánh dấu nó là chấp nhận.
Kevin Fegan

Câu trả lời:


4

Hãy thử một kịch bản như thế này:

#!/bin/bash
echo "to fd1" >&1
echo "to fd2" >&2
echo "to screen" >$(tty)

Khi bạn gọi nó, nó trông như thế này:

user@host:~# ./script
to fd1
to fd2
to screen
user@host:~# ./script 1>/dev/null
to fd2
to screen
user@host:~# ./script 2>/dev/null
to fd1
to screen
user@host:~# ./script > /dev/null 2>&1
to screen

>/dev/ttytốt hơn >$(tty)bởi vì nó hoạt động ngay cả khi stdin được chuyển hướng và nó không phải trải qua điệu nhảy cố gắng quét xung quanh /devcho đến khi tìm thấy thiết bị chính xác.
Celada

2

Tôi không biết về tất cả các chuyển hướng tty, nhưng đây là những gì tôi làm:

Không thực sự chuyển hướng, nhưng gửi đầu ra bạn muốn dưới dạng tham số hoặc, nếu bạn đang chuyển hướng trong chính tập lệnh, bạn có thể chuyển hướng chuyển hướng bất cứ lúc nào bằng cách thực hiện:

exec 2> /some/new/destination 1> /some/other/destination

nhưng bạn có thể muốn cứu những cái cũ ...

exec  3>&1 4>&2 2> /some/new/destination 1> /some/other/destination

bằng cách đó bạn có thể quay lại với nó ... khi bạn hoàn thành hoặc muốn viết lên màn hình

viết lên màn hình: echo "message" 1>&3

hoặc là..

tất cả đã xong: exec 1>&3 2>&4 # mọi thứ trở lại bình thường :)


0

Sử dụng ví dụ từ câu trả lời của sự hỗn loạn :

echo "to screen" >$(tty)

đã không làm việc cho tôi. Tôi gặp lỗi khi cố gắng sử dụng nó:

./myscript.sh: line xx: /dev/pts/3: Permission denied

Tôi đã đưa ra một giải pháp để sử dụng một mô tả tập tin khác (9). Đây là "./myscript.sh":

#!/bin/sh -u

## This is placed one time at the top of the script  
## to detect if file descriptor (9) is available for writing.
if [ ! -t 3 ]; then
    echo "Error, file descriptor (9) not open on terminal." >&2
    echo "" >&2
    if [ ! -t 2 ]; then
        echo "Error, file descriptor (9) not open on terminal."
        echo ""
    fi
    exit 1
fi

echo "Message A: This writes to stdout or wherever '1>' redirects to."
echo "Message B: This writes to stdout or wherever '1>' redirects to.">&1
echo "Message C: This writes to stderr or wherever '2>' redirects to.">/dev/stderr
echo "Message D: This writes to stderr or wherever '2>' redirects to.">&2
echo "Message E: Write this to 'screen' regardless of '1>/2>' redirection." >&9
echo " " >&9

Tôi đã sử dụng bộ mô tả tệp 9để xuất các thông báo "trạng thái" sang, nhưng các bộ mô tả tệp hợp lệ khác sẽ hoạt động.

Để sử dụng nó, khi gọi tập lệnh, bạn phải bao gồm chuyển hướng mô tả tệp (9) sang STDOUT (9> & 1) làm chuyển hướng đầu tiên.

Đây là đầu ra khi tôi gọi "./myscript.sh":

[~]# ./myscript.sh
[~]# ./myscript.sh >/dev/null
[~]# ./myscript.sh 2>/dev/null
Error, file descriptor (9) not open on terminal.

[~]# ./myscript.sh >/dev/null 9>&1
Error, file descriptor (9) not open on terminal.

[~]# ./myscript.sh 9>&1 >/dev/null
Message C: This writes to stderr or wherever '2>' redirects to.
Message D: This writes to stderr or wherever '2>' redirects to.
Message E: Write this to 'screen' regardless of '1>/2>' redirection.

[~]# ./myscript.sh 9>&1 2>/dev/null
Message A: This writes to stdout or wherever '1>' redirects to.
Message B: This writes to stdout or wherever '1>' redirects to.
Message E: Write this to 'screen' regardless of '1>/2>' redirection.

[~]# ./myscript.sh 9>&1 >/dev/null 2>&1
[~]# ./myscript.sh 9>&1 &>/dev/null
[~]# ./myscript.sh 9>&1 >&/dev/null
Message E: Write this to 'screen' regardless of '1>/2>' 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.