Một số thủ thuật về chuyển hướng
Một số đặc thù cú pháp về điều này có thể có hành vi quan trọng. Có một số mẫu ít về chuyển hướng, STDERR
, STDOUT
, và đối số đặt hàng .
1 - Ghi đè hoặc nối thêm?
Biểu tượng >
có nghĩa là chuyển hướng .
>
có nghĩa là gửi đến toàn bộ tệp đã hoàn thành , ghi đè mục tiêu nếu tồn tại (xem noclobber
tính năng bash ở # 3 sau).
>>
có nghĩa là gửi thêm vào sẽ nối vào mục tiêu nếu tồn tại.
Trong mọi trường hợp, tệp sẽ được tạo nếu chúng không tồn tại.
2 - Dòng lệnh shell phụ thuộc vào thứ tự !!
Để kiểm tra điều này, chúng ta cần một lệnh đơn giản sẽ gửi một cái gì đó trên cả hai đầu ra :
$ ls -ld /tmp /tnt
ls: cannot access /tnt: No such file or directory
drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp
$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt 2>/dev/null
drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp
(Dự kiến bạn không có một thư mục có tên /tnt
;). Vâng, chúng tôi có nó !!
Vì vậy, hãy xem:
$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt >/dev/null 2>&1
$ ls -ld /tmp /tnt 2>&1 >/dev/null
ls: cannot access /tnt: No such file or directory
Dòng lệnh cuối cùng đổ STDERR
vào bảng điều khiển và dường như đó không phải là hành vi được mong đợi ... Nhưng ...
Nếu bạn muốn thực hiện một số lọc bài đăng về một đầu ra, đầu ra khác hoặc cả hai:
$ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
<-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp --->
$ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
<-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp --->
$ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt >/dev/null 2>&1 | sed 's/^.*$/<-- & --->/'
$ ls -ld /tmp /tnt 2>&1 >/dev/null | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
Lưu ý rằng dòng lệnh cuối cùng trong đoạn này hoàn toàn giống như trong đoạn trước, nơi tôi đã viết dường như không phải là hành vi dự kiến (vì vậy, đây thậm chí có thể là một hành vi dự kiến).
Vâng, có một mẹo nhỏ về chuyển hướng, để
thực hiện các thao tác khác nhau trên cả hai đầu ra :
$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2 2>&1 | sed 's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan 7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory
Nota: &9
mô tả sẽ xảy ra tự phát vì) 9>&2
.
Phụ lục: không!Với phiên bản mới củabash( >4.0
) có một tính năng mới và cú pháp gợi cảm hơn để thực hiện loại điều này:
$ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
E: ls: cannot access /tnt: No such file or directory
Và cuối cùng cho định dạng đầu ra xếp tầng như vậy:
$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1| cat -n
1 O: drwxrwxrwt 118 root root 196608 Jan 7 12:29 /tmp
2 E: ls: cannot access /tnt: No such file or directory
Phụ lục: không! Cùng một cú pháp mới, theo cả hai cách:
$ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /'))
1 O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
2 E: ls: cannot access /tnt: No such file or directory
Khi STDOUT
đi qua một bộ lọc cụ thể, STDERR
đến một bộ lọc khác và cuối cùng cả hai đầu ra được hợp nhất sẽ đi qua bộ lọc lệnh thứ ba.
3 - Một từ về noclobber
tùy chọn và >|
cú pháp
Đó là về ghi đè :
Trong khi set -o noclobber
hướng dẫn bash không ghi đè lên bất kỳ tệp hiện có nào, >|
cú pháp cho phép bạn vượt qua giới hạn này:
$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:15 CET 2013
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:19 CET 2013
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:21 CET 2013
Các tập tin được ghi đè mỗi lần, ngay bây giờ:
$ set -o noclobber
$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan 7 13:18:21 CET 2013
$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan 7 13:18:21 CET 2013
Đi qua với >|
:
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:18:58 CET 2013
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:19:01 CET 2013
Bỏ cài đặt tùy chọn này và / hoặc tìm hiểu nếu đã được đặt.
$ set -o | grep noclobber
noclobber on
$ set +o noclobber
$ set -o | grep noclobber
noclobber off
$ date > $testfile ; cat $testfile
Mon Jan 7 13:24:27 CET 2013
$ rm $testfile
4 - Thủ thuật cuối cùng và hơn thế nữa ...
Để chuyển hướng cả hai đầu ra từ một lệnh đã cho, chúng tôi thấy rằng một cú pháp đúng có thể là:
$ ls -ld /tmp /tnt >/dev/null 2>&1
trong trường hợp đặc biệt này, có một cú pháp tắt: &>
... hoặc>&
$ ls -ld /tmp /tnt &>/dev/null
$ ls -ld /tmp /tnt >&/dev/null
Nota: nếu 2>&1
tồn tại, 1>&2
cũng là một cú pháp đúng:
$ ls -ld /tmp /tnt 2>/dev/null 1>&2
4b- Bây giờ, tôi sẽ cho phép bạn suy nghĩ về:
$ ls -ld /tmp /tnt 2>&1 1>&2 | sed -e s/^/++/
++/bin/ls: cannot access /tnt: No such file or directory
++drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/
$ ls -ld /tmp /tnt 1>&2 2>&1 | sed -e s/^/++/
/bin/ls: cannot access /tnt: No such file or directory
drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/
4c- Nếu bạn quan tâm đến nhiều thông tin hơn
Bạn có thể đọc hướng dẫn sử dụng tốt bằng cách nhấn:
man -Len -Pless\ +/^REDIRECTION bash
trong một bash bảng điều khiển ;-)