Bu 'at' komutu neden standart çıktıya yazdırılmıyor?


15

Ben göreceli bir Linux acemisiyim. Nasıl kullanılacağını öğrenmek için çalışıyorum, atböylece daha sonra kullanmak için görevleri zamanlamak için kullanabilirsiniz sleep. Bu önceki soruya yardım için bakıyordum .

Benim sorum, oluşturduğum aşağıdaki örnek bash betiğinde, neden "Çalışıyor" - hiçbir zaman söyleyebildiğim kadarıyla - standart çıktıya (yani bash konsolum) yazdırılmıyor?

#!/bin/bash

echo "Started"

at now + 1 minutes <<EOF
echo "Running"
EOF

echo "Finished"

Gördüğüm tek çıktı, örneğin:

Started
warning: commands will be executed using /bin/sh
job 3 at Fri Jul 12 17:31:00 2013
Finished

Sorumun cevabında uyarı var mı? Öyleyse /bin/sh, standart çıktıdan farkı nedir?


sleep 3m; echo Running
Şunu

Yanıtlar:


18

Çünkü atoturum açmış olduğunuz kullanıcı oturumu bağlamında komutları çalıştırmaz. Fikir, rastgele bir zamanda çalışacak bir komutu programlayabilmeniz, daha sonra oturumu kapatmanız ve sistemin komutu belirtilen zamanda çalıştırmayı başarabilmenizdir.

Bu kılavuz sayfasının at(1)özellikle şunu vurguladığını (benim vurguladığım):

Kullanıcıya standart hata ve varsa komutlarından standart çıktı gönderilecektir . Posta / usr / sbin / sendmail komutu kullanılarak gönderilecektir.

Bu nedenle, yerel posta biriktiricinizi veya başarısız olursa yerel sistem posta günlüklerini kontrol etmelisiniz. / var / spool / mail / $ USER muhtemelen başlamak için iyi bir yerdir.

Ayrıca, "Başlatıldı" ve "Bitti" ifadelerinin dış komut dosyasından kaynaklandığını ve kendi başlarına hiçbir ilgileri olmadığını unutmayın at. Onları veya atçağrıyı çıkarabilir ve esasen aynı sonucu alırsınız.


8

@ MichaelKjörling'in açıkladığı gibi, atişiniz tarafından üretilen herhangi bir çıktı yakalanacak ve size e-posta ile gönderilecektir. Kutunuzda çalışan bir MTA - Posta Aktarım Aracısı yoksa, e-posta limbo olabilir ve bunun atbunu yapmaya çalıştığını bile bilemezsiniz .

MTA, e-postayı uygun bir hedefe "teslim edebilen" sendmailveya benzeri bir programdır postfix. Bu durumda /var/spool/mail, yerel sisteminizdeki bir posta kuyruğuna (dizinin altındaki bir dosyaya) gönderir . Sistemdeki her kullanıcının bu dizinde bir kuyruğu olabilir.

Fedora sistemimde başlarsam sendmailyerel posta teslimi gerçekleşebilir. Genellikle olsa kapalı var.

$ sudo service start sendmail

Artık kullanıcı hesabım için posta kuyruğumun samlboş olduğunu görebiliyoruz:

$ ll /var/spool/mail/|grep saml
-rw-rw----. 1 saml mail       0 Jul 12 19:33 saml

Şimdi atişi biz yürütüyoruz:

$ at now + 1 minutes <<EOF
echo "Running"
EOF
job 96 at Fri Jul 12 19:38:00 2013

İşin birlikte çalışmayı beklediğini görebiliriz atq:

$ atq
96  Fri Jul 12 19:38:00 2013 a saml

Birkaç dakika sonra tekrar çalıştırdığınızda, atişin tamamlandığını görebiliriz:

$ atq
$

Bu arada, MTA'm çalışırken şimdi şu mesajı terminalime alıyorum:

/ Var / spool / mail / saml'de yeni postanız var

Öyleyse kontrol edelim:

$ ll /var/spool/mail/|grep saml
-rw-rw----. 1 saml mail     651 Jul 12 19:38 saml

Evet, postalarımız var, bu yüzden şunu kullanarak kontrol edelim mutt:

$ mutt -f /var/spool/mail/saml

Bunu posta kuyruğumuzun "gelen kutusu" nda bulabilirsiniz:

     mutt gelen kutusunun ss

Bu e-postayı kontrol edelim:

     köpekbalığı mesajı

Ve işe yaradı.


@ MichaelKjörling - mutt rulz 8-)
slm

5

Debian 8.1 (jessie) kullanıyorum
. 'At' çıkışının tty kullanarak bir terminale gitmesini sağlayabilirsiniz.

$ tty
/dev/pts/1

$ at now + 1 min
warning: commands will be executed using /bin/sh
at> echo 'ZZZZZ' > /dev/pts/1
at> <EOT>

Bir dakika sonra terminalinizde 'ZZZZZ' görünecek ...


2

Yukarıdaki cevaplar bunu yapmanın standart / "doğru" yoludur.

Daha "son kullanıcı" bakış açısından daha basit olan bir diğer yaklaşım, zamanlanmış veya arka plandaki herhangi bir görevin çıktısını bir "günlük" dosyasına yazmasını sağlamaktır. Dosya sisteminizde herhangi bir yerde olabilir, ancak görev kök (kimden cronvb.) Olarak çalışıyorsa, altında /var/logbir yere koymak için iyi bir yerdir.

/var/log/maintDizini oluşturdum ve herkes tarafından okunabilir hale getirdim ve "yedekleme" adı altında okunabilir bir dosyaya sahibim.

Kendi dizinimi oluşturdum, böylece dosyalarım sistem tarafından oluşturulan şeylerle karışmıyor.

Oraya bir şeyler koymak için:

BACKUP="/var/log/maint/backup"
echo "my message" >> "${BACKUP}"

>>Mesajlar yerine o her zaman yazılmadan dosyasına eklenecek neden olur.

Komut dosyamda çok fazla çıktı varsa, çıktı için bir komut dosyası veya işlev kullanırım, böylece her şey aynı şekilde yapılır. Aşağıda benim mevcut (overkill sürümü): (Senaryoyu bir terminalden çalıştırdığımda ve hata ayıklama amacıyla neler olduğunu görmek istediğinizde VERBOSE şeyler var.)

#!/bin/bash
## backup_logger
## backup system logging module
## Copyleft 01/20/2013 JPmicrosystems
## Usage is ${SCRIPT_NAME} [-v] [<caller> <log message text>]
## If present, -v says log to console as well as to the log file
## <caller> is the name of the calling script
## If <caller> <log message text> is not present, write a blank line to the log

## Must be placed in path, like ~/bin
## If log is owned by root or another user, then this must run as root ...
## If not, it just aborts

##source "/home/bigbird/bin/bash_trace"  ## debug
SCRIPT_NAME="$(basename $0)"
USAGE="Usage is ${SCRIPT_NAME} [-v] [<caller> <log message text>]"
SYSLOGDIR='/var/log/maint'
SYSLOGFILE="${SYSLOGDIR}/backup.log"

LOGGING=1
VERBOSE=0
if [ "${1}" == "-v" ]
then
  VERBOSE=1
  shift
fi

##LOGGING=0  ## debug
##VERBOSE=1  ## debug

## Only zero or two parameters allowed - <caller> <log message text>
RC=0
if [ "$#" -eq 1 ] || [ "$#" -gt 2 ]
then
  echo "${USAGE}"
  RC=1
else
  if [ ! -w "${SYSLOGFILE}" ]
  then
    touch "${SYSLOGFILE}"
    if [ $? -ne 0 ]
    then
      echo -e "$(date) ${1} ${2}"
      echo "${SCRIPT_NAME} Can't write to log file [${SYSLOGFILE}]"
      RC=1
      exit ${RC}
    fi
  fi

  if [ -n "${1}" ]
  then
    (( LOGGING )) && echo -e "$(date) ${1} ${2}"  >> "${SYSLOGFILE}"
    (( VERBOSE )) && echo -e "$(date) ${1} ${2}"
  else
    (( LOGGING )) && echo "" >> "${SYSLOGFILE}"
    (( VERBOSE )) && echo ""
  fi
fi

exit $RC

Düzenleme: atBir kullanıcı dosyasına yazılan basit örnek

Bunu sonsuza kadar kullanmadım, bu yüzden birkaç basit komut dosyasıyla anladım.

İlk komut dosyası olayı kullanarak zamanlar at. Komutun kendisi sadece bir terminale yazılabilir, ama tembelim - özellikle komut geçmişini kandırmadan test ederken birden fazla kez yapmak zorunda kaldığımda.

#!/bin/bash
## mytest_at_run
## Schedule a script to run in the immediate future
echo "/home/bigbird/bin/mytest_at_script" | at 00:56

İkinci komut dosyası, çalıştırılması planlanan komut dosyasıdır

#!/bin/bash
## mytest_at_script
## The script to be run later
echo "$(date) - is when this ran" >> /home/bigbird/log/at.log

Her iki komut dosyasını da bir metin düzenleyicide oluşturdum, sakladım ve her birini kullanarak çalıştırılabilir yaptım chmod 700 script-file-name. Her ikisini de $HOME/binkolaylık sağlamak için dizinime koydum , ancak kullanıcılarımın tam erişime sahip olduğu her yerde olabilirler. 700Sadece test için herhangi bir komut dosyası için kullanıyorum , ancak tek bir kullanıcı sisteminde de olabilir 755.

Zaten /home/bigbird/logçıktı kaydetmek için adlı bir dizin var mytest_at_script. Bu, kullanıcılarınızın tam erişime sahip olduğu her yerde de olabilir. Komut dosyası çalıştırmadan önce var olduğundan emin olun veya komut dosyasını oluşturmasını sağlayın.

Çalıştırmak için, atkomutun zamanının mytest_at_rungelecekte biraz olduğundan emin oldum ve bir terminalden çalıştırdım. Sonra o kadar koştu ve içeriğini inceledim bekledi $HOME/log/at.log.

bigbird@sananda:~/bin$ cat ~/log/at.log
Fri Sep 14 00:52:18 EDT 2018 - is when this ran
Fri Sep 14 00:56:00 EDT 2018 - is when this ran
bigbird@sananda:~/bin$

Birkaç not:

Koşuyorum rağmen atbenim kullanıcıdan, böyle benim olarak benim ortamını bilmiyor PATHben varsayalım kalmamak ve benim ev dizininde. Herhangi bir croniş için yaptığım gibi tam yolları kullanıyorum . Ve eğer bunu bir croniş yapmak istersem, sadece onu çalıştırmak için hiçbir şeyi değiştirmem gerekmeyecek.

Günlük dosyasına çıktı eklemek için kullandım >>, mytest_at_scriptbunun yerine >her çalıştırmada değiştirirdim. Uygulamanız için en uygun olanı kullanın.


Bana AT komutunu kullanarak günlük dosyasına çıktı yazmak için herhangi bir örnek verebilir misiniz, ben şu şekilde deniyorum ama sonuç yok, şu anda + echo "" merhaba ">> / home / camsarch / cams_scripts / texsttest. txt at> <EOT>
Pavan Kumar Varma

@PavanKumarVarma - atbir dosyaya yazmak için kullanarak basit (test edilmiş) bir örnek ekledi . Örneğinizde arama sırasını geri aldığınız anlaşılıyor. atİşi ne zaman yapacağımı söylemede pek iyi değilim , bu yüzden yakın zamanda bir zaman kodladım.
Joe
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.