Meminta perintah / skrip terputus dari terminal pengendali?

9

Saya sedang menyelidiki perilaku skrip yang biasanya dijalankan sebagai proses otomatis (misalnya cron, Jenkins). Script dapat (akhirnya) menjalankan perintah yang berperilaku berbeda (mencari input pengguna) ketika dijalankan secara interaktif; misalnya, patchakan bertanya apa yang harus dilakukan dengan tambalan yang dibalik, dan svnakan meminta kata sandi, tetapi saya perlu melihat apa yang terjadi ketika mereka dijalankan secara non-interaktif.

Membujuk patchbahwa itu non-interaktif cukup mudah; Saya hanya perlu mengarahkan ulang stdoutmenjadi non-tty:

$ </dev/null > >(cat) /path/to/myscript --args

Namun svnakan terhubung ke terminal pengendali jika ada; mengedit skrip untuk dilewati --non-interactivebukan pilihan karena ini berasal dari beberapa level dan akan sulit untuk memastikan bahwa saya telah menemukan setiap doa.

Apakah ada cara untuk memanggil skrip / perintah secara non-interaktif, tanpa terminal pengendali (sehingga /dev/ttytidak ada)? Saya lebih suka stdout / stderr untuk tetap pergi ke terminal saya.

(Saya menemukan pertanyaan Jalankan skrip di shell non-interaktif? Tetapi jawaban untuk itu membahas perbedaan antara cron dan lingkungan pengguna; Saya sudah menghilangkan semua perbedaan kecuali non-interaktivitas.)

ecatmur
sumber

Jawaban:

13

Anda perlu memulai sesi lain yang tidak terhubung ke terminal, jadi misalnya:

$ setsid sh -c 'tty; ps -jp "$$"; echo test' < /dev/null > log 2>&1
$ cat log
not a tty
  PID  PGID   SID TTY          TIME CMD
19506 19506 19506 ?        00:00:00 sh
test

Lihat juga start-stop-daemonperintah yang ditemukan di beberapa distribusi Linux. Ada juga daemonperintah.

Stéphane Chazelas
sumber
Apa artinya output ini? Terlihat sangat samar.
anatoly techtonik
2
@anatolytechtonik bagian-bagian penting adalah "bukan tty" yang merupakan output dari ttykonfirmasi tidak ada terminal di stdin, dan "?" di kolom TTY psoutput yang mengkonfirmasi tidak ada tty mengendalikan untuk shproses (dan apa pun yang berjalan di bawahnya).
mr.spuratic
Untuk menjalankan perintah seperti perintah lainnya, gunakan setsid -w. Contoh: setsid -w sh -c 'tty < /dev/tty'memberi sh: 1: cannot open /dev/tty: No such device or address(Catatan: /dev/ttyadalah tty Anda yang mengendalikan). Tanpa -wsetsid menjalankan proses secara paralel / latar belakang.
Tino
0

Anda mungkin ingin membuat skrip harapan. Contoh dengan SVN:

/programming/609445/using-expect-to-login-into-svn

Bratchley
sumber
Itu tidak berhasil; harapkan menjalankan perintah secara interaktif.
ecatmur
Secara interaktif dalam arti apa? Dalam artian itu membutuhkan input dari pengguna? Jika itu yang Anda maksud, tidak akan ada gunanya berharap ada dalam kasus itu. Salah satu contoh yang saya gunakan adalah pada Solaris, perintah passwd tidak memiliki opsi --stdin jadi saya memiliki cronjob yang mengatur skrip ekspektasi yang membungkus passwd untuk memberinya password acak untuk sebuah akun. Tidak diperlukan interaksi manusia. Ini pemahaman saya bahwa ini adalah kebutuhan pengguna. Tapi aku bisa salah paham.
Bratchley
Sebenarnya semakin saya membaca ulang ini, semakin saya sadar saya salah paham akan apa yang Anda tuju. Permintaan maaf.
Bratchley
0

Terkadang Anda harus tetap membuka stdin (tidak menerima eof on stdin) (mis. Berharap). Dalam hal ini ubah / dev / null ke / dev / zero.

setsid sh -c 'make test' </dev/zero >log 2>&1
Roger
sumber