Bisakah saya menambahkan "&& prog2" ke prog1 yang sudah berjalan?

87

Kebanyakan shell menyediakan fungsi seperti &&dan ;untuk mengaitkan eksekusi perintah dengan cara tertentu. Tetapi bagaimana jika suatu perintah sudah berjalan, apakah saya masih dapat menambahkan perintah lain untuk dijalankan tergantung pada hasil dari yang pertama?

Katakan aku berlari

$ /bin/myprog
some output...

tapi aku sangat menginginkannya /bin/myprog && /usr/bin/mycleanup. Saya tidak bisa membunuh myprogdan memulai kembali semuanya karena terlalu banyak waktu akan hilang. Saya dapat Ctrl+ Zdan fg/ bgjika perlu. Apakah ini memungkinkan saya untuk mengikat perintah lain?

Saya sebagian besar tertarik pada bash, tetapi jawaban untuk semua shell umum dipersilahkan!

us2012
sumber

Jawaban:

118

Anda harus bisa melakukan ini di shell yang sama dengan waitperintah:

$ sleep 30 &
[1] 17440

$ wait 17440 && echo hi

...30 seconds later...
[1]+  Done                    sleep 30
hi

kutipan dari halaman manual Bash

wait [n ...]
     Wait for each specified process and return its termination status. Each n 
     may be a process ID or a job specification; if a job spec is given,  all 
     processes  in that job's pipeline are waited for.  If n is not given, all 
     currently active child processes are waited for, and the return status is 
     zero.  If n specifies a non-existent process or job, the return status is 
     127.  Otherwise, the return status is the exit status of the last process 
     or job waited for.
slm
sumber
Menunggu perintah harus melakukan pekerjaan.
BillThor
Ada sejumlah formulir pendek untuk memasukkan PID dari proses berlatar belakang seperti %, %1dan $!. Penting untuk memasok PID atau perintah kedua akan selalu berjalan.
BillThor
@ BillThor - apakah Anda hanya memenuhi syarat jawaban atau memberi tahu saya ini?
slm
Saya memenuhi syarat jawabannya. Dataran waitakan gagal memberikan hasil yang diinginkan. Adalah umum untuk menggunakan formulir pendek karena mereka kurang rentan terhadap kesalahan ketik.
BillThor
2
Biarkan saya menjadi yang pertama untuk memberi selamat Anda pada lencana baru Anda yang mengkilap :)
terdon
63

fgkembali dengan kode keluar dari program yang dilanjutkannya. Karena itu Anda dapat menangguhkan program Anda dengan ^Zdan kemudian gunakan fg && ...untuk melanjutkannya.

$ /bin/myprog
some output...
^Z
[1]+ Stopped              /bin/myprog
$ fg && /usr/bin/mycleanup
John Kugelman
sumber
jika Anda menunda lagi sebelum berakhir dan melakukan hal yang sama dengan perintah yang berbeda, apakah rantai awal mycleanup bisa diganti?
Burhan Ali
3
@ BurhanAli Menangguhkan myproguntuk kedua kalinya menyebabkan fguntuk mengakhiri dengan kode keluar 20 - yang tidak nol, sehingga mycleanupperintah dirantai tidak dieksekusi.
n.
1

Tidak yakin apakah yang Anda minta itu mungkin, tetapi jika Anda masih memiliki shell tempat Anda memulai program, Anda selalu dapat memeriksa $?status keluar proses terakhir:

$ /bin/myprog
some output...
$ if [ $? -ne 0 ];then echo "non-zero exit status";else echo "0 exit status";fi
Joseph R.
sumber
1
Ini akan berhasil, tetapi dia harus menjalankan ini secara manual setelah itu, dia ingin menjalankan ini secara otomatis ketika perintah selesai.
slm
@slm Setuju. Saya tidak punya solusi untuk masalah itu.
Joseph R.
3
Periksa waitperintah di Bash.
slm
1

Jika pekerjaan di latar depan, salah satu dari perintah ini akan memiliki perilaku yang sama seperti yang Anda harapkan.

[ $? -eq 0 ] && prog2
(( $? )) || prog2

CATATAN: $? akan berisi status pengembalian program yang sedang berjalan saat keluar.

Ini secara eksplisit menyatakan apa yang akan dilakukan shell jika Anda awalnya memasukkan perintah.

prog1 && prog2

Jika perintah pertama tidak dibaca dari stdindan sedang berjalan di latar depan, perintah baru dapat dimasukkan saat perintah pertama sedang berjalan. Shell akan membaca dan menjalankannya ketika perintah pertama dijalankan. Jika perintah akan berjalan di latar belakang, tidak mungkin itu membaca stdin.

EDIT: Menempatkan pekerjaan di latar belakang dan menggunakan WAITperintah juga bisa digunakan. Ini harus dilakukan dengan hati-hati jika pekerjaan lain juga dijalankan di latar belakang. Spesifikasi pekerjaan diperlukan agar WAITperintah mengembalikan status pekerjaan yang ditunggu.

BillThor
sumber
Ini akan berhasil, tetapi dia harus menjalankan ini secara manual setelah itu, dia ingin menjalankan ini secara otomatis ketika perintah selesai.
slm
4
@slm Selama perintah tidak membaca stdin, perintah baru dapat dimasukkan saat perintah pertama sedang berjalan. Shell akan membacanya segera setelah perintah pertama selesai.
BillThor
Jika dia melakukan sesuatu dalam shell setelah latar belakang itu kemungkinan disembunyikan. Setidaknya sesuai dengan pendahuluan. pengujian yang telah saya lakukan sejauh ini!
slm
2
@ BillThor Saya pikir Anda harus menambahkan komentar itu ke jawaban Anda.
Joseph R.
2
Ya, menggunakan waitjuga tidak ideal. Keuntungannya, IMO, adalah memberi kita API yang lebih jelas yang sedang kita hadapi. Mengetik lebih banyak perintah pada baris perintah setelah ada sesuatu yang berjalan terasa agak membingungkan bagi saya. waitmasih menderita karena tidak mendapatkan tautan langsung ke PID yang sedang berjalan, wrt status pengembalian. Ini tampaknya menjadi masalah lebih banyak w / bagaimana Bash mengimplementasikan sesuatu: stackoverflow.com/questions/356100/… . Jadi ini mungkin sama baiknya dengan yang didapat.
slm