Suka kesederhanaan jawaban ini. FYI, Anda harus dapat menambahkan flag -f ke pgrep, dan Anda kemudian dapat memeriksa nama proses lengkap, yang berguna jika Anda juga ingin memeriksa argumen untuk proses sebagai bagian dari kondisi Anda.
Craig Sefton
6
Tidak, Anda tidak dapat menggunakan flag -f dengan pgrep di dalam cronjob. Alasannya adalah bahwa Anda akan cocok dengan skrip shell yang digunakan untuk menjalankan cronjob itu sendiri.
CpnCrunch
Saat menjalankan proses GUI dengan cron, tambahkan terlebih dahulu export DISPLAY=:0untuk mencegah Could not connect to displaykesalahan. * * * * * export DISPLAY=:0 && pgrep processname > /dev/null || /path/to/processname -args0 -args1
Benjam
9
Jalankan skrip, alih-alih langsung program. Ada banyak kemungkinan. Sebagai contoh :
MYPROG="myprog"
RESTART="myprog params"
PGREP="/usr/bin/pgrep"
# find myprog pid
$PGREP ${MYPROG}
# if not running
if [ $? -ne 0 ]
then
$RESTART
fi
FYI - menggunakan variabel skalar untuk menyimpan daftar argumen dianggap praktik buruk. Lihat mywiki.wooledge.org/BashFAQ/050 untuk contoh kasus gagal.
Charles Duffy
... sama halnya, pgrep myprog; if [ $? -ne 0 ]; then ...akan lebih baik ditulis sebagaiif ! pgrep myprog; then ...
Charles Duffy
... gaya yang terakhir ini tidak hanya lebih mudah dibaca, tetapi juga lebih sedikit rawan kesalahan: Sangat mudah untuk secara tidak sengaja mengganggu nilai $?, misalnya dengan menambahkan pesan log atau penanganan kesalahan di antara baris.
Charles Duffy
7
Script ini tidak akan berjalan lagi jika instance sebelumnya belum selesai. Jika Anda ingin tidak menjalankan sesuatu jika proses spesifik lain sedang berjalan, lihat skrip harrymc.
DATE=`date +%c`;
ME=`basename "$0"`;
LCK="./${ME}.LCK";
exec 8>$LCK;
if flock -n -x 8; then
echo ""
echo "Starting your script..."
echo ""
[PUT YOUR STUFF HERE]
echo ""
echo "Script started $DATE";
echo "Script finished `date +%c`";
else
echo "Script NOT started - previous one still running at $DATE";
fi
bagus sekarang rsync atas garis lambat ini dapat mengambil semua waktu yang dibutuhkan, menembak dalam waktu 5 menit dari host klien yang datang online tanpa intervensi manual:*/5 * * * * root flock /run/shm rsync -auhx --numeric-ids -e "ssh -T -c arcfour128 -o Compression=no -x" [source] [user]@[host]:[dest]
eMPee584
1
Ini biasanya ditangani oleh program itu sendiri daripada oleh cron. Ada dua teknik standar untuk ini:
1) grepoutput psuntuk melihat apakah ada proses dengan nama yang sudah berjalan
2) Pada saat startup, pertama periksa keberadaan file pid (proses id), biasanya di /var/run/program_name.pid, dan, jika ada, baca pid keluar dari file dan periksa apakah proses itu masih ada; jika ya, menolak untuk memulai. Jika file pid tidak ada atau pid dalam file sudah hilang, maka buat file pid, tulis id proses Anda ke dalamnya, dan lanjutkan dengan startup normal.
Meskipun secara teknis dimungkinkan untuk menulis bash pipes yang akan melakukan salah satu dari ini langsung ke crontab Anda, lebih baik menambahkannya ke program yang sedang dimulai (sehingga mereka akan menerapkannya tidak peduli bagaimana itu dimulai) atau untuk menulis skrip wrapper ke tangani ini, seperti yang disarankan harrymc.
Saya telah menggunakan kembali jawaban di atas dengan perbaikan dalam pencocokan pola. pgrep tanpa opsi f tidak cocok dengan pola proses. Namun ada masalah dengan menggunakan opsi f. Dengan opsi f, shell yang memunculkan cron selalu cocok dan mengembalikan pidnya sehingga prosesnya tidak pernah dimulai ulang.
Menambahkan [] di sekitar salah satu pola huruf hanya cocok dengan proses dan pid dari cron shell tidak dikembalikan.
Jawaban:
cara paling sederhana, gunakan pgrep
di crontab:
sumber
export DISPLAY=:0
untuk mencegahCould not connect to display
kesalahan.* * * * * export DISPLAY=:0 && pgrep processname > /dev/null || /path/to/processname -args0 -args1
Jalankan skrip, alih-alih langsung program. Ada banyak kemungkinan. Sebagai contoh :
sumber
pgrep myprog; if [ $? -ne 0 ]; then ...
akan lebih baik ditulis sebagaiif ! pgrep myprog; then ...
$?
, misalnya dengan menambahkan pesan log atau penanganan kesalahan di antara baris.Script ini tidak akan berjalan lagi jika instance sebelumnya belum selesai. Jika Anda ingin tidak menjalankan sesuatu jika proses spesifik lain sedang berjalan, lihat skrip harrymc.
sumber
Anda dapat menggunakan file kunci dalam skrip Anda, tetapi silakan lihat Manajemen Proses .
flock
adalah salah satu utilitas yang bisa digunakan.sumber
*/5 * * * * root flock /run/shm rsync -auhx --numeric-ids -e "ssh -T -c arcfour128 -o Compression=no -x" [source] [user]@[host]:[dest]
Ini biasanya ditangani oleh program itu sendiri daripada oleh
cron
. Ada dua teknik standar untuk ini:1)
grep
outputps
untuk melihat apakah ada proses dengan nama yang sudah berjalan2) Pada saat startup, pertama periksa keberadaan file pid (proses id), biasanya di
/var/run/program_name.pid
, dan, jika ada, baca pid keluar dari file dan periksa apakah proses itu masih ada; jika ya, menolak untuk memulai. Jika file pid tidak ada atau pid dalam file sudah hilang, maka buat file pid, tulis id proses Anda ke dalamnya, dan lanjutkan dengan startup normal.Meskipun secara teknis dimungkinkan untuk menulis bash pipes yang akan melakukan salah satu dari ini langsung ke crontab Anda, lebih baik menambahkannya ke program yang sedang dimulai (sehingga mereka akan menerapkannya tidak peduli bagaimana itu dimulai) atau untuk menulis skrip wrapper ke tangani ini, seperti yang disarankan harrymc.
sumber
* * * * * pgrep -f "[p]attern" > /dev/null || /path/to/processname -args0 -args1
Saya telah menggunakan kembali jawaban di atas dengan perbaikan dalam pencocokan pola. pgrep tanpa opsi f tidak cocok dengan pola proses. Namun ada masalah dengan menggunakan opsi f. Dengan opsi f, shell yang memunculkan cron selalu cocok dan mengembalikan pidnya sehingga prosesnya tidak pernah dimulai ulang.
Menambahkan [] di sekitar salah satu pola huruf hanya cocok dengan proses dan pid dari cron shell tidak dikembalikan.
sumber