Uyuyan bir bash betiğini nasıl uyandırabilirim?


27

sleepKomut kullanılarak duraklatılmış bir işlemi uyandırmak mümkün mü ?


Örnek olarak, bu komut dosyasına sahip olduğunuzu varsayalım:

#!/bin/bash
echo "I am tired"
sleep 8h
echo "I am fresh :)"

30 dakika sonra, komut dosyasının durması için ihtiyacınız olduğunu keşfedersiniz, yani sleep 30mbunun yerine yazmayı dilediniz .

Aramak kill PIDveya Ctrl+ tuşuna basmak istemezsiniz C, çünkü son komut çalıştırılmaz ve yorgun kalırsınız.

Süreci uyandırmanın sleepya da uyanmayı destekleyen başka bir komutu kullanmanın bir yolu var mı ? Hem arka plan hem de ön plan işlemlerine yönelik çözümler açıktır.


13
Bağırma, gerçekten yüksek sesle.
Doorknob

2
@Dnoorknob gawking gerçekten çalışmıyor. En son bir sleepişlemim oldu pushd, yataktan kalktım.
imallett

Komut dosyanızda bir #!satır eksik . Ve konularda Sorunuzun cevabı herhangi olup olmadığını bağlıdır çünkü -eiçinde #!hat.
kasperd

1
@ kasperd Tamam. Meraktan: -e bayrağının etkisi nedir?
Bittenus

2
Varsayılan olarak, bir hatadan sonra bir komut dosyası devam edecek. Kullanırsanız #!/bin/bash -e, komut dosyası bir hatadan sonra durur. Sadece uyku komutunu öldürmek, bash tarafından bir hata olarak değerlendirilecektir. Bu -e, sorunuzu cevaplamadan oldukça basit bir cevap olduğu anlamına gelir . Eğer -ekullanıldıysa, çok zorlaşır çünkü uyku sürecini öldürmeden durdurmanız gerekir.
kasperd

Yanıtlar:


47

Bir Bash betiği çalışırken sleep, pstreeşöyle görünebilir:

bash(10102)───sleep(8506)

Her ikisi de, bir komut dosyası olarak çalışırken bile işlem kimlikleri (PID) içerir. Eğer uykuyu kesmek isteseydik gönderirdik kill 8506ve Bash oturumu devam ederdi ... Sorun senaryolu bir ortamda sleepkomutun PID'sini bilmiyoruz ve sürece bakacak bir insan yok ağacı.

Bash oturumunun PID'ini $$sihirli değişken aracılığıyla alabiliriz . Bunu bir yerde saklayabilirsek, sleepo zaman PID'nin altında çalışan örneklerini hedefleyebiliriz . İşte senaryoya koyduğum şey:

# write the current session's PID to file
echo $$ >> myscript.pid

# go to sleep for a long time
sleep 1000

Sonra pkillPID'nin sleepaltında çalışan nükleer örnekleri söyleyebiliriz :

pkill -P $(<myscript.pid) sleep

Yine, bu yalnızca kendisini sleepdoğrudan tek bir Bash oturumu altında çalışan işlemlerle sınırlandırıyor . PID doğru bir şekilde kaydedildiği sürece, bu işlem onu killall sleepveya sistemden çok daha güvenli kılar ve bu da sistemdeki herhangi bir işlemi pkill sleepiptal edebilir (izinler izin verir). sleep

Bu teoriyi, şu an iki örnekle üç ayrı bash oturumumuzun olduğu aşağıdaki örnekte kanıtlayabiliriz sleep. Sadece sol üst bash oturumunun PID'sini belirttiğimiz için, sadece bu sleepöldürülür.

görüntü tanımını buraya girin


Alternatif bir yaklaşım, sleeparka plana itmek , PID'sini saklamak ve daha sonra ön plana döndürmektir. Kodda:

sleep 1000 &
echo $! > myscript.sleep.pid
fg

Ve onu öldürmek için:

kill $(<myscript.sleep.pid)

5

Komut dosyanızı, öldürme vb. Gibi diğer sinyalleri işlemek ("tuzak") için yazabilirsiniz, böylece komut dosyası davranışını gerektiği gibi değiştirebilirsiniz. Adam bash'a bakınız:

SIGNALS
   When  bash  is  interactive,  in the absence of any traps, it ignores SIGTERM (so that kill 0 does not
   kill an interactive shell), and SIGINT is caught and handled (so that the wait builtin  is  interrupt-
   ible).   In all cases, bash ignores SIGQUIT.  If job control is in effect, bash ignores SIGTTIN, SIGT-
   TOU, and SIGTSTP.

   Non-builtin commands run by bash have signal handlers set to the values inherited by  the  shell  from
   its  parent.   When  job  control is not in effect, asynchronous commands ignore SIGINT and SIGQUIT in
   addition to these inherited handlers.  Commands run as a result of  command  substitution  ignore  the
   keyboard-generated job control signals SIGTTIN, SIGTTOU, and SIGTSTP.

   The shell exits by default upon receipt of a SIGHUP.  Before exiting, an interactive shell resends the
   SIGHUP to all jobs, running or stopped.  Stopped jobs are sent SIGCONT to ensure that they receive the
   SIGHUP.   To  prevent the shell from sending the signal to a particular job, it should be removed from
   the jobs table with the disown builtin (see SHELL BUILTIN COMMANDS below) or  marked  to  not  receive
   SIGHUP using disown -h.

   If  the huponexit shell option has been set with shopt, bash sends a SIGHUP to all jobs when an inter-
   active login shell exits.

   If bash is waiting for a command to complete and receives a signal for which a trap has been set,  the
   trap  will not be executed until the command completes.  When bash is waiting for an asynchronous com-
   mand via the wait builtin, the reception of a signal for which a trap has been set will cause the wait
   builtin  to  return immediately with an exit status greater than 128, immediately after which the trap
   is executed.

4

Sadece senaryonun bir sonraki satırına devam edecek olan uykuyu öldürebilirsin:

pkill sleep

Bunun sadece betiğinizde değil, sisteminizde çalışan herhangi bir uyku sürecini de öldüreceğini unutmayın.


1

cronAçılışta başladığım uyku bash betiğim var . Senaryo her dakika uyanır ve internetten elde edilen gün doğumu ve gün batımına göre dizüstü bilgisayar ekranının parlaklığını ayarlar. Tam parlak ve tam loş arasındaki kullanıcı tarafından yapılandırılabilir bir geçiş aşaması, değerlerin 3, 4, 5 oranında düşürülmesi veya düşürülmesini veya her dakika hesaplanan her şeyi gerektirir.

Oli pstreecevabına kısaca değindi, ancak bütün sleepörnekleri öldüreceği için reddetti . Bu, pstree seçeneklerini kullanarak aramayı daraltarak önlenebilir.

Kullanarak pstree -htüm heirarşiyi görüyoruz:

$ pstree -h
systemd─┬─ModemManager─┬─{gdbus}
                      └─{gmain}
        ├─NetworkManager─┬─dhclient
                        ├─dnsmasq
                        ├─{gdbus}
                        └─{gmain}
        ├─accounts-daemon─┬─{gdbus}
                         └─{gmain}
        ├─acpid
        ├─agetty
        ├─atd
        ├─avahi-daemon───avahi-daemon
        ├─cgmanager
        ├─colord─┬─{gdbus}
                └─{gmain}
        ├─cron───cron───sh───display-auto-br───sleep
        ├─cups-browsed─┬─{gdbus}
                      └─{gmain}
        ├─dbus-daemon
        ├─fwupd─┬─3*[{GUsbEventThread}]
               ├─{fwupd}
               ├─{gdbus}
               └─{gmain}
        ├─gnome-keyring-d─┬─{gdbus}
                         ├─{gmain}
                         └─{timer}
        ├─irqbalance
        ├─lightdm─┬─Xorg───3*[{Xorg}]
                 ├─lightdm─┬─upstart─┬─at-spi-bus-laun─┬─dbus-daemon
                                                    ├─{dconf worker}
                                                    ├─{gdbus}
                                                    └─{gmain}
                                   ├─at-spi2-registr─┬─{gdbus}
                                                    └─{gmain}
                                   ├─bamfdaemon─┬─{dconf worker}
                                               ├─{gdbus}
                                               └─{gmain}
                                   ├─chrome─┬─2*[cat]
                                           ├─chrome─┬─chrome─┬─2*[chrome─┬─{Chrome_ChildIOT}]
                                                                      ├─5*[{CompositorTileW}]]
                                                                      ├─{Compositor}]
                                                                      ├─{GpuMemoryThread}]
                                                                      ├─{MemoryInfra}]
                                                                      ├─{Renderer::FILE}]
                                                                      ├─{TaskSchedulerRe}]
                                                                      └─{TaskSchedulerSe}]
                                                           ├─7*[chrome─┬─{Chrome_ChildIOT}]
                                                                      ├─5*[{CompositorTileW}]]
                                                                      ├─{Compositor}]
                                                                      ├─{GpuMemoryThread}]
                                                                      ├─{MemoryInfra}]
                                                                      ├─{Renderer::FILE}]
                                                                      ├─{ScriptStreamerT}]
                                                                      ├─{TaskSchedulerRe}]
                                                                      └─{TaskSchedulerSe}]
                                                           ├─chrome─┬─{Chrome_ChildIOT}
                                                                   ├─5*[{CompositorTileW}]
                                                                   ├─{Compositor}
                                                                   ├─{GpuMemoryThread}
                                                                   ├─{Media}
                                                                   ├─{MemoryInfra}
                                                                   ├─{Renderer::FILE}
                                                                   ├─{ScriptStreamerT}
                                                                   ├─{TaskSchedulerRe}
                                                                   └─{TaskSchedulerSe}
                                                           └─2*[chrome─┬─{Chrome_ChildIOT}]
                                                                       ├─5*[{CompositorTileW}]]
                                                                       ├─{Compositor}]
                                                                       ├─{GpuMemoryThread}]
                                                                       ├─{Renderer::FILE}]
                                                                       ├─{ScriptStreamerT}]
                                                                       ├─{TaskSchedulerRe}]
                                                                       └─{TaskSchedulerSe}]
                                                   └─nacl_helper
                                           ├─chrome─┬─chrome
                                                   ├─{Chrome_ChildIOT}
                                                   ├─{MemoryInfra}
                                                   ├─{TaskSchedulerSe}
                                                   └─{Watchdog}
                                           ├─{AudioThread}
                                           ├─{BrowserWatchdog}
                                           ├─{Chrome_CacheThr}
                                           ├─{Chrome_DBThread}
                                           ├─{Chrome_FileThre}
                                           ├─{Chrome_FileUser}
                                           ├─{Chrome_HistoryT}
                                           ├─{Chrome_IOThread}
                                           ├─{Chrome_ProcessL}
                                           ├─{Chrome_SyncThre}
                                           ├─{CompositorTileW}
                                           ├─{CrShutdownDetec}
                                           ├─{D-Bus thread}
                                           ├─{Geolocation}
                                           ├─{IndexedDB}
                                           ├─{LevelDBEnv}
                                           ├─{MemoryInfra}
                                           ├─{NetworkChangeNo}
                                           ├─{Networking Priv}
                                           ├─4*[{TaskSchedulerBa}]
                                           ├─6*[{TaskSchedulerFo}]
                                           ├─{TaskSchedulerSe}
                                           ├─{WorkerPool/3166}
                                           ├─{WorkerPool/5824}
                                           ├─{WorkerPool/5898}
                                           ├─{WorkerPool/6601}
                                           ├─{WorkerPool/6603}
                                           ├─{WorkerPool/7313}
                                           ├─{chrome}
                                           ├─{dconf worker}
                                           ├─{extension_crash}
                                           ├─{gdbus}
                                           ├─{gmain}
                                           ├─{gpu-process_cra}
                                           ├─{inotify_reader}
                                           ├─{renderer_crash_}
                                           ├─{sandbox_ipc_thr}
                                           └─{threaded-ml}
                                   ├─compiz─┬─{dconf worker}
                                           ├─{gdbus}
                                           ├─{gmain}
                                           └─8*[{pool}]
                                   ├─conky───6*[{conky}]
                                   ├─2*[dbus-daemon]

( .... many lines deleted to fit in 30k limit .... )

        ├─vnstatd
        ├─whoopsie─┬─{gdbus}
                  └─{gmain}
        └─wpa_supplicant

Gördüğünüz gibi tipik bir Ubuntu girişi, birçok PID (İşlem Kimliği) içerir.

Aşağıdakileri kullanarak çalışan komut dosyasına daraltabiliriz:

$ pstree -g -p | grep display-auto
  |-cron(1198,1198)---cron(1257,1198)---sh(1308,1308)---display-auto-br(1321,1308)---sleep(26552,1308)

Görürüz:

  • cron Bir kabuk başlattı (işlem kimliği 1308 ve oturum kimliği 1308)
  • Kabuk, 1321 işlem kimliği ve oturum kimliği 1308 (kabuk eşleştirme) altında çalışan programımızı çağırıyor
  • Programımız sleepişlem kimliği 26552 ve yine oturum kimliği 1308'i çağırıyor

Bu noktada kullanabiliriz pkill -s 1308ve kabuğumuzu, programımızı display-auto-brightnessve sleepkomutunu içeren tüm oturumu öldürür . Bunun yerine kill 26552, programımızı uyandırmaya ve parlaklığı ayarlamaya zorlayan sadece uyku komutunu öldürmek için kullanacağız .

Bunu manüel olarak yazdığınız terminale yazın:

───────────────────────────────────────────────────────────────────────────────
rick@dell:~$ pstree -g -p | grep display-auto
             |-cron(1198,1198)---cron(1257,1198)---sh(1308,1308)---display-auto-br(1321,1308)---sleep(32362,1308)
───────────────────────────────────────────────────────────────────────────────
rick@dell:~$ sudo kill 32362
───────────────────────────────────────────────────────────────────────────────
rick@dell:~$ pstree -g -p | grep display-auto
             |-cron(1198,1198)---cron(1257,1198)---sh(1308,1308)---display-auto-br(1321,1308)---sleep(1279,1308)
───────────────────────────────────────────────────────────────────────────────
rick@dell:~$ sudo kill 1279
───────────────────────────────────────────────────────────────────────────────
rick@dell:~$ pstree -g -p | grep display-auto
             |-cron(1198,1198)---cron(1257,1198)---sh(1308,1308)---display-auto-br(1321,1308)---sleep(4440,1308)
───────────────────────────────────────────────────────────────────────────────
rick@dell:~$ 

Bir sonraki adım, dizüstü bilgisayar askıya alındıktan sonra bunu yapmaktır. Örneğin, kapak kapalıyken tamamen karanlıktı ve ekran parlaklığı "300" olarak ayarlandı. Kapak açıldığında günışığıdır ve parlaklığın "2000" olarak ayarlanması gerekir. Tabii ki program 1 ila 59 saniye içinde kendi kendine uyanır, ancak parlaklığın anında ayarlanması daha rahattır.

Askıya alma / devam etme kodunu yazıldıktan sonra gönderirim. Umarım bu haftasonu.

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.