apa perbedaan antara `>> / dev / stderr` (dengan ruang putih) dan`> & 2`?


11

Di bash.

Saya mengalami kesulitan untuk menentukan apa yang harus saya gunakan?

semua skrip saya menggunakan ">> / dev / stderr"

di bash prompt, jika saya mencoba:
echo test >>/dev/stderrworks
echo test >> /dev/stderrworks
echo test >/dev/stderrworks
echo test > /dev/stderrworks

echo test >>&2GAGAL!
echo test >> &2GAGAL!
echo test >&2bekerja
echo test > &2GAGAL!

Saya bersedia mengubah semua skrip saya >&2.

Tampaknya juga memiliki efek besar pada ssh (setelah su SomeUser) di mana >>/dev/stderrtidak akan berfungsi sama sekali (izin ditolak), hanya >&2akan berfungsi.


dapatkah Anda menunjukkan contoh kesalahan ssh? Saya tidak bisa mereproduksi.
Jeff Schaller

@JeffSchaller Anda benar, Hanya setelah sumasalah itu terjadi, memperbarui pertanyaan
Aquarius Power

@AquariusPower, ... untuk menjelaskan perbedaan itu, omong-omong: dengan su -c 'some command', perintah itu dijalankan oleh /bin/sh, bukan bash, jadi perilaku spesifik-bash (seperti simulasi /dev/stderruntuk tujuan pengalihan bila tidak tersedia) tidak dijamin untuk hadir.
Charles Duffy

Jawaban:


22

>& nadalah sintaks shell untuk secara langsung menduplikasi file descriptor . Deskripsi file 2 adalah stderr; begitulah cara kerjanya. Anda dapat menduplikasi file deskriptor lain juga, bukan hanya stderr. Anda tidak dapat menggunakan mode append di sini karena menduplikasi deskriptor file tidak pernah terpotong (bahkan jika stderr Anda adalah file) dan >&merupakan salah satu token, itu sebabnya Anda tidak dapat menempatkan spasi di dalamnya — tetapi >& 2berfungsi.

>> nameadalah sintaks yang diizinkan yang berbeda, di mana nameada nama file (dan tokennya >>). Dalam hal ini, Anda menggunakan nama file /dev/stderr, yang oleh penanganan khusus OS (di Linux, itu symlink ke /proc/self/fd/2) juga berarti kesalahan standar. Mode tambah dan terpotong keduanya berakhir melakukan hal yang sama ketika stderr adalah terminal karena itu tidak dapat terpotong. Namun, jika kesalahan standar Anda adalah file, itu akan dipotong:

anthony@Zia:~$ bash -c 'echo hi >/dev/stderr; echo bye >/dev/stderr' 2>/tmp/foo
anthony@Zia:~$ cat /tmp/foo
bye

Jika Anda melihat kesalahan dengan /dev/stderrlebih dari ssh, mungkin admin server telah menerapkan beberapa tindakan keamanan yang mencegah symlink tersebut berfungsi. (Misalnya, Anda tidak dapat mengakses /procatau /dev). Sementara saya berharap salah satu penyebab kerusakan aneh, menggunakan sintaks deskriptor file duplikat adalah pendekatan yang masuk akal (dan mungkin sedikit lebih efisien). Secara pribadi saya lebih suka itu.


Saya mengalami masalah besar dalam mencoba mereplikasi masalah terpotong yang saya miliki sebelumnya (kalau tidak saya akan menambahkan itu ke pertanyaan hehe), alasan saya mengubah segalanya untuk digunakan >>, terima kasih untuk menunjukkan itu! Juga, saya melewatkan langkah su SomeUsersetelah menghubungkan melalui ssh.
Aquarius Power

ini bash -c 'echo hi >&2; echo bye >&2' 2>/tmp/foo;cat /tmp/footidak akan memotong tho! (bahkan dengan 2>&1 |tee /tmp/foo) apa yang sempurna untuk penebangan, dan akan berfungsi dengan baik setelah saya ubah semuanya >&2. Jadi saya kira hanya penggunaan file secara langsung yang /dev/stderrmemungkinkan truncating, bukan deskriptor yang diduplikasi, cool thx!
Aquarius Power

@ AquariusPower benar, deskriptor file duplikat tidak pernah terpotong. Itu di paragraf pertama, mungkin saya perlu menyorotnya entah bagaimana?
derobert

tidak diperlukan, kadang-kadang saya lambat ya
Aquarius Power

3
Jawaban ini bisa diperbaiki. > & adalah salah satu token bukan dua dan ada kebohongan OP.
Joshua

8

Kasus kegagalan terjadi karena sintaks bash untuk digunakan &dalam pengalihan menentukan satu >, dan mengharuskan itu ada berbatasan langsung dengan &tanda:

[n]> & kata


2

Gunakan '>'untuk mengalihkan (memotong jika ada) atau '>>'(menambahkan jika ada).

Gunakan '>&'untuk menduplikasi aliran, misalnya, jika Anda ingin output standar DAN kesalahan standar dalam file yang sama, Anda mengarahkan ulang ke file '> output.log'dan juga kesalahan dengan'2>&'

myjob.sh > output.log 2>&
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.