Apa yang dilakukan `<& -`?

20

Saya menyalin cuplikan Bash ke latar belakang perintah ssh yang dijalankan dari jarak jauh:

ssh user@remote <<CMD
some process <&- >log 2>error &
CMD

Apa yang <&-harus dilakukan
Dugaan saya adalah bahwa itu sama dengan< /dev/null

Pemahaman saya berikutnya adalah bahwa tiga deskriptor file utama ( stdin, stdout, stderr) perlu ditutup untuk mencegah:

  1. Pekerjaan yang dilatar belakangi dan skrip yang keluar - entah bagaimana bertentangan?
  2. Ketika terminal ditutup, semua proses yang menerima stdin dari terminal ditutup?
Eric Francis
sumber
Referensi silang wajib: Lihat Apa kontrol shell dan operator redirection? - walaupun semua yang tertulis tentang operator ini adalah "dapat digunakan untuk menutup atau menduplikasi file deskriptor" dan Anda harus "melihat bagian yang relevan dari manual shell Anda".
G-Man Mengatakan 'Reinstate Monica'
Jika saya ingat dengan benar, ssh -nNT user@remote 'command'akan membuat sesi SSH non-interaktif. Tambahkan &ke latar belakang, tambahkan nohupke commandagar tetap berjalan jika koneksi Anda mati.
Mark K Cowan
1
@MarkKCowan man sshmenyarankan bahwa -N menonaktifkan menjalankan perintah jarak jauh sepenuhnya, dan tes cepat mendukungnya.
Tom Hunt
Ah ya, saya menggunakan -nNTR untuk membalikkan port forwarding. Abaikan -N dan -R lalu :)
Mark K Cowan

Jawaban:

30

<&-tidak persis sama dengan < /dev/null. <&-menutup fd 0, sedangkan < /dev/nullmengalihkannya dari perangkat /dev/null, yang tidak pernah memberikan data apa pun dan selalu memberikan EOF saat dibaca. Perbedaannya adalah sebagian besar bahwa read(2)panggilan dari FD tertutup ( <&-kasing) akan kesalahan dengan EBADF, sedangkan panggilan dari FD redirect yang diarahkan tidak akan menghasilkan pembacaan byte (kondisi akhir file). Jika program Anda tidak pernah membaca dari stdin, perbedaannya tidak masalah.

Menutup FD adalah praktik yang baik jika Anda melatar belakangi sesuatu, karena proses latar belakang akan hang jika mencoba membaca apa pun dari TTY. Contoh ini tidak sepenuhnya menangani semua yang seharusnya; idealnya akan ada nohupatau setsiddoa di suatu tempat, untuk sepenuhnya melepaskan proses latar belakang.

Tom Hunt
sumber
Jadi saya harus menggunakan nohupselain untuk menutup file deskriptor?
Eric Francis
2
Metode yang paling teliti (yang meniru cara program daemonize sendiri) adalah sesuatu seperti setsid some process <&- >path/to/log 2>path/to/error. Metode yang lebih cepat adalah sesuatu seperti nohup some process &.
Tom Hunt
2
@EricFrancis: Menggunakan nohuptidak masuk akal di sini. nohupmencegah proses menerima HUPsinyal ketika terminal kontrolnya ditutup. Tetapi Anda tidak memiliki terminal dalam hal ini.
cuonglm
@ TomHunt: Proses latar belakang tidak menggantung, sesi ssh berhasil.
cuonglm
2
bukan ide yang baik untuk menutup fds 0, 1 & 2 ... Anda tidak ingin fd berikutnya dibuat untuk mengambil salah satu dari nilai-nilai itu. lebih baik untuk mengarahkan mereka ke / dev / null
Murray Jensen
7

Lihat man bash:

  [n]<&word

digunakan untuk menduplikasi deskripsi file input. Jika worddiperluas ke satu atau lebih digit, deskriptor file yang dilambangkan dengan ndibuat menjadi salinan deskriptor file itu. Jika digit di word tidak menentukan deskriptor file yang terbuka untuk input, terjadi kesalahan redirection. Jika kata dievaluasi -, deskriptor file nditutup. Jika ntidak ditentukan, input standar (file descriptor 0) digunakan.

choroba
sumber
Definisi yang benar adalah bahwa itu tidak ditentukan apa yang terjadi ketika Anda memiliki [n]<&worddan kata mengandung lebih dari satu digit.
schily
Apa maksudmu? Apakah itu man bashsalah?
Eric Francis
@EricFrancis karena tidak ditentukan dalam standar, bashmemilih untuk mengimplementasikannya dengan cara yang waras (untuk beberapa definisi "waras" yang sesuai). Kerang lain mungkin atau mungkin tidak melakukannya.
muru
@muru Pertanyaannya ditandai bash, bukan posix-shell.
Barmar
@Barmar ok. Begitu...?
muru
7

<&- tutup input standar.

Bentuk umum, yang didefinisikan oleh POSIX , adalah:

[n]<&word

Tujuannya untuk membuat file deskriptor nadalah salinan deskriptor file yang ditandai oleh word. Standar diasumsikan jika ndihilangkan, dan jika wordini -, file descriptor nakan ditutup.

Ini tidak sama dengan </dev/null, karena ketika dalam kasus </dev/null, input standar masih terbuka, dan dialihkan ke tempat lain.

Anda perlu menutup semua file deskriptor proses yang dilampirkan ke soket ssh, jika tidak, sesi ssh tidak dapat ditutup.

Anda dapat menjalankan perintah pada mesin jarak jauh tanpa melampirkannya ke sesi ssh, dengan menggunakan layar atau tmux :

ssh user@remote 'screen -S test -d -m command'
cuonglm
sumber
Mengapa memilih bawah?
cuonglm