Beberapa trik tentang pengalihan
Beberapa sintaksis tertentu tentang hal ini mungkin memiliki perilaku penting. Ada beberapa sampel sedikit tentang pengalihan, STDERR
, STDOUT
, dan argumen pemesanan .
1 - Menimpa atau menambahkan?
Simbol >
berarti pengalihan .
>
berarti kirim ke sebagai keseluruhan file yang sudah selesai , timpa target jika ada (lihat noclobber
fitur bash di # 3 nanti).
>>
berarti mengirim dan menambahkan akan menargetkan jika ada.
Bagaimanapun, file akan dibuat jika tidak ada.
2 - Baris perintah shell tergantung pesanan !!
Untuk menguji ini, kita memerlukan perintah sederhana yang akan mengirim sesuatu pada kedua output :
$ 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
(Mengharapkan Anda tidak memiliki direktori bernama /tnt
, tentu saja;). Baiklah, kita memilikinya !!
Jadi, mari kita lihat:
$ 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
Baris perintah terakhir kesedihan STDERR
ke konsol, dan tampaknya bukan perilaku yang diharapkan ... Tapi ...
Jika Anda ingin membuat beberapa pemfilteran posting tentang satu output, yang lain atau keduanya:
$ 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 --->
Perhatikan bahwa baris perintah terakhir dalam paragraf ini persis sama dengan paragraf sebelumnya, di mana saya menulis tampaknya bukan perilaku yang diharapkan (jadi, ini bahkan bisa menjadi perilaku yang diharapkan).
Nah, ada sedikit trik tentang pengalihan, untuk
melakukan operasi yang berbeda pada kedua output :
$ ( 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
Catatan: &9
deskriptor akan terjadi secara spontan karena ) 9>&2
.
Tambahan: nota! Dengan versi barupesta( >4.0
) ada fitur baru dan sintaksis yang lebih seksi untuk melakukan hal-hal semacam ini:
$ 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
Dan akhirnya untuk format output berjenjang:
$ ((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
Tambahan: nota! Sintaks baru yang sama, dalam dua hal:
$ 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
Di mana STDOUT
pergi melalui filter tertentu, STDERR
ke yang lain dan akhirnya kedua output digabungkan melalui filter perintah ketiga.
3 - Sepatah kata tentang noclobber
opsi dan >|
sintaksis
Itu tentang menimpa :
Meskipun set -o noclobber
menginstruksikan bash untuk tidak menimpa file yang ada, >|
sintaksnya membiarkan Anda melewati batasan ini:
$ 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
File ditimpa setiap kali, nah sekarang:
$ 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
Lewati dengan >|
:
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:18:58 CET 2013
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:19:01 CET 2013
Membatalkan pilihan ini dan / atau bertanya apakah sudah disetel.
$ 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 - Trik terakhir dan banyak lagi ...
Untuk mengarahkan ulang kedua output dari perintah yang diberikan, kita melihat bahwa sintaks yang tepat adalah:
$ ls -ld /tmp /tnt >/dev/null 2>&1
untuk kasus khusus ini, ada sintaks pintasan: &>
... atau>&
$ ls -ld /tmp /tnt &>/dev/null
$ ls -ld /tmp /tnt >&/dev/null
Nota: jika 2>&1
ada, 1>&2
adalah sintaks yang benar juga:
$ ls -ld /tmp /tnt 2>/dev/null 1>&2
4b- Sekarang, saya akan membiarkan Anda berpikir tentang:
$ 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- Jika Anda tertarik pada informasi lebih lanjut
Anda dapat membaca manual yang bagus dengan menekan:
man -Len -Pless\ +/^REDIRECTION bash
di sebuah pesta konsol ;-)