Bir *NIX sisteminin zamanlanmış cron işlerinin tümünü aynı anda görüntülememi sağlayacak bir komut veya mevcut bir betik var mı? Tüm kullanıcı crontab'larının yanı sıra /etc/crontab
ve /etc/cron.d
içindeki her şeyi içermesini istiyorum. Ayrıca /etc/crontab
içinde run-parts
tarafından çalıştırılan belirli komutları görmek de güzel olurdu.
İdeal olarak, çıktının güzel bir sütun biçiminde olmasını ve anlamlı bir şekilde sıralanmasını istiyorum.
Daha sonra bu listeleri birden fazla sunucudan birleştirerek genel "etkinlik programını" görüntüleyebilirim;
Ben de böyle bir senaryo yazmak üzereydim ama eğer birileri çoktan bu zahmete girmişse...
Bunu root olarak çalıştırmanız gerekir, ancak:
for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l; done
crontab'larını listeleyen her kullanıcı adı üzerinde döngü oluşturacaktır. Crontab'lar ilgili kullanıcılara aittir, bu nedenle başka bir kullanıcının crontab'ını o veya root olmadan göremezsiniz.
Düzenle
bir crontab'ın hangi kullanıcıya ait olduğunu bilmek istiyorsanız, echo $user
kullanın
for user in $(cut -f1 -d: /etc/passwd); do echo $user; crontab -u $user -l; done
Sonunda bir betik yazdım (kendime bash betik yazmanın inceliklerini öğretmeye çalışıyorum, bu yüzden burada Perl gibi bir şey görmüyorsunuz). Tam olarak basit bir iş değil, ama ihtiyacım olan şeyin çoğunu yapıyor. Bireysel kullanıcıların crontab'larına bakmak için Kyle'ın önerisini kullanıyor, ama aynı zamanda /etc/crontab
ile de ilgileniyor (/etc/cron.hourly
, /etc/cron.daily
, vs. içindeki run-parts
tarafından başlatılan betikler dahil) ve /etc/cron.d
dizinindeki işler. Bunların hepsini alır ve aşağıdaki gibi bir görüntüde birleştirir:
mi h d m w user command
09,39 * * * * root [ -d /var/lib/php5 ] && find /var/lib/php5/ -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 | xargs -r -0 rm
47 */8 * * * root rsync -axE --delete --ignore-errors / /mirror/ >/dev/null
17 1 * * * root /etc/cron.daily/apt
17 1 * * * root /etc/cron.daily/aptitude
17 1 * * * root /etc/cron.daily/find
17 1 * * * root /etc/cron.daily/logrotate
17 1 * * * root /etc/cron.daily/man-db
17 1 * * * root /etc/cron.daily/ntp
17 1 * * * root /etc/cron.daily/standard
17 1 * * * root /etc/cron.daily/sysklogd
27 2 * * 7 root /etc/cron.weekly/man-db
27 2 * * 7 root /etc/cron.weekly/sysklogd
13 3 * * * archiver /usr/local/bin/offsite-backup 2>&1
32 3 1 * * root /etc/cron.monthly/standard
36 4 * * * yukon /home/yukon/bin/do-daily-stuff
5 5 * * * archiver /usr/local/bin/update-logs >/dev/null
Kullanıcıyı gösterdiğini ve günlük programı görebilmem için az çok saat ve dakikaya göre sıraladığını unutmayın.
Şimdiye kadar Ubuntu, Debian ve Red Hat AS üzerinde test ettim.
#!/bin/bash
# System-wide crontab file and cron job directory. Change these for your system.
CRONTAB='/etc/crontab'
CRONDIR='/etc/cron.d'
# Single tab character. Annoyingly necessary.
tab=$(echo -en "\t")
# Given a stream of crontab lines, exclude non-cron job lines, replace
# whitespace characters with a single space, and remove any spaces from the
# beginning of each line.
function clean_cron_lines() {
while read line ; do
echo "${line}" |
egrep --invert-match '^($|\s*#|\s*[[:alnum:]_]+=)' |
sed --regexp-extended "s/\s+/ /g" |
sed --regexp-extended "s/^ //"
done;
}
# Given a stream of cleaned crontab lines, echo any that don't include the
# run-parts command, and for those that do, show each job file in the run-parts
# directory as if it were scheduled explicitly.
function lookup_run_parts() {
while read line ; do
match=$(echo "${line}" | egrep -o 'run-parts (-{1,2}\S+ )*\S+')
if [[ -z "${match}" ]] ; then
echo "${line}"
else
cron_fields=$(echo "${line}" | cut -f1-6 -d' ')
cron_job_dir=$(echo "${match}" | awk '{print $NF}')
if [[ -d "${cron_job_dir}" ]] ; then
for cron_job_file in "${cron_job_dir}"/* ; do # */ <not a comment>
[[ -f "${cron_job_file}" ]] && echo "${cron_fields} ${cron_job_file}"
done
fi
fi
done;
}
# Temporary file for crontab lines.
temp=$(mktemp) || exit 1
# Add all of the jobs from the system-wide crontab file.
cat "${CRONTAB}" | clean_cron_lines | lookup_run_parts >"${temp}"
# Add all of the jobs from the system-wide cron directory.
cat "${CRONDIR}"/* | clean_cron_lines >>"${temp}" # */ <not a comment>
# Add each user's crontab (if it exists). Insert the user's name between the
# five time fields and the command.
while read user ; do
crontab -l -u "${user}" 2>/dev/null |
clean_cron_lines |
sed --regexp-extended "s/^((\S+ +){5})(.+)$/\1${user} \3/" >>"${temp}"
done < <(cut --fields=1 --delimiter=: /etc/passwd)
# Output the collected crontab lines. Replace the single spaces between the
# fields with tab characters, sort the lines by hour and minute, insert the
# header line, and format the results as a table.
cat "${temp}" |
sed --regexp-extended "s/^(\S+) +(\S+) +(\S+) +(\S+) +(\S+) +(\S+) +(.*)$/\1\t\2\t\3\t\4\t\5\t\6\t\7/" |
sort --numeric-sort --field-separator="${tab}" --key=2,1 |
sed "1i\mi\th\td\tm\tw\tuser\tcommand" |
column -s"${tab}" -t
rm --force "${temp}"
Cron sürümünüze bağlı olarak değişir. FreeBSD üzerinde Vixie cron kullanarak şöyle bir şey yapabilirim:
(cd /var/cron/tabs && grep -vH ^# *)
Eğer daha fazla sekmenin silinmesini istersem, şöyle bir şey yapabilirim:
(cd /var/cron/tabs && grep -vH ^# * | sed "s/:/ /")
Burada sed değiştirme kısmında gerçek bir sekme vardır.
etc/passwdiçindeki kullanıcılar arasında döngü yapmak ve her biri için
crontab -l -u $user` yapmak sistemden daha bağımsız olabilir.