मैं स्लीपिंग बैश स्क्रिप्ट कैसे जगा सकता हूं?


27

क्या sleepकमांड का उपयोग करके रोक दी गई प्रक्रिया को जगाना संभव है ?


एक उदाहरण के रूप में, आपको यह स्क्रिप्ट देने की अनुमति देता है:

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

30 मिनट के बाद आपको पता चलता है कि आपको रुकने के लिए स्क्रिप्ट की आवश्यकता है, अर्थात्, आपने कामना की है कि आपने sleep 30mइसके बजाय लिखा था ।

आप करते हैं या तो कॉल नहीं करना चाहता kill PIDया प्रेस Ctrl+ C, के बाद से तो पिछले आदेश निष्पादित नहीं कर रहा है और आप थक गए रहेगा।

क्या इस प्रक्रिया को जागृत करने का एक तरीका है sleepया शायद एक अन्य कमांड का उपयोग करें जो वेकूप का समर्थन करता है? पृष्ठभूमि और अग्रभूमि दोनों प्रक्रियाओं के समाधान का स्वागत है।


13
यह वास्तव में जोर से चिल्लाओ।
डोरकनॉब

2
@Doorknob gawkआईएनजी वास्तव में काम नहीं करता है। पिछली बार मेरे पास sleepआईएनजी प्रक्रिया थी, मैंने pushdइसे बिस्तर से हटा दिया।
imallett

आपकी स्क्रिप्ट एक #!पंक्ति याद आ रही है । और यह मायने रखता है क्योंकि आपके प्रश्न का उत्तर इस बात पर निर्भर करता है कि क्या लाइन -eमें कोई है #!
कास्परड

1
@kasperd किया। जिज्ञासा से: -ई झंडे का क्या प्रभाव है?
बीटनस

2
डिफ़ॉल्ट रूप से एक स्क्रिप्ट एक त्रुटि के बाद जारी रहेगी। यदि आप उपयोग करते हैं #!/bin/bash -e, तो स्क्रिप्ट एक त्रुटि के बाद बंद हो जाएगी। बस स्लीप कमांड को मारने से बैश को एक त्रुटि माना जाएगा। इसका मतलब है कि -eआपके प्रश्न के बिना काफी सरल उत्तर है। यदि -eउपयोग किया गया था, तो यह बहुत कठिन हो जाता है क्योंकि आपको इसे मारने के बिना नींद की प्रक्रिया को रोकने की आवश्यकता होगी।
कास्परड

जवाबों:


47

जब एक बैश स्क्रिप्ट चल रही है sleep, तो यहां क्या pstreeहो सकता है:

bash(10102)───sleep(8506)

स्क्रिप्ट के रूप में चलने पर भी दोनों के पास आईडी (पीआईडी) प्रक्रिया है। यदि हम नींद में बाधा डालना चाहते हैं, तो हम भेजेंगे kill 8506और बैश सत्र फिर से शुरू होगा ... समस्या एक पटकथा वाले वातावरण में है जिसे हम sleepकमांड की पीआईडी ​​नहीं जानते हैं और इस प्रक्रिया को देखने के लिए मानव नहीं है। पेड़।

हम मैश $$चर के माध्यम से बैश सत्र के पीआईडी ​​प्राप्त कर सकते हैं । अगर हम इसे कहीं स्टोर कर सकते हैं, तो हम उस PID के नीचेsleep चल रहे उदाहरणों को लक्षित कर सकते हैं । यहाँ मैं स्क्रिप्ट में क्या डालूँगा:

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

# go to sleep for a long time
sleep 1000

और फिर हम उस PID के नीचे चलने वाले pkillnuke sleepइंस्टेंस को बता सकते हैं :

pkill -P $(<myscript.pid) sleep

फिर, यह केवल sleepउस एक बैश सत्र के तहत सीधे चलने वाली प्रक्रियाओं तक ही सीमित है । जब तक PID को सही तरीके से लॉग किया गया था, यह इसे बहुत सुरक्षित बनाता है killall sleepया pkill sleep, जो सिस्टम पर किसी भी sleep प्रक्रिया को न्यूड कर सकता है (अनुमति अनुमति)।

हम निम्नलिखित उदाहरण के साथ उस सिद्धांत को साबित कर सकते हैं जहां हमारे पास तीन अलग-अलग बैश सत्र हैं, दो चल रहे हैं sleep। केवल इसलिए कि हम शीर्ष-बाएं बैश सत्र के पीआईडी ​​को निर्दिष्ट कर रहे हैं, केवल इसकी sleepहत्या हुई है।

यहाँ छवि विवरण दर्ज करें


एक वैकल्पिक दृष्टिकोण sleepपृष्ठभूमि में धक्का देना है, अपने पीआईडी ​​को स्टोर करना है और फिर इसे अग्रभूमि में वापस करना है। स्क्रिप्ट में:

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

और इसे मारने के लिए:

kill $(<myscript.sleep.pid)

5

आप अपनी स्क्रिप्ट को हैंडल ("ट्रैप") अन्य संकेतों को मारने आदि से लिख सकते हैं ताकि आप स्क्रिप्ट के व्यवहार को आवश्यकतानुसार संशोधित कर सकें। देखें मैन बैश:

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

आप सिर्फ नींद को मार सकते हैं जो स्क्रिप्ट की अगली पंक्ति तक जारी रहेगी:

pkill sleep

ध्यान दें कि यह आपके सिस्टम में न केवल आपके स्क्रिप्ट में चलने वाली किसी भी नींद की प्रक्रिया को मार देगा।


1

मेरे पास एक स्लीपिंग बैश स्क्रिप्ट है cronजो बूट पर शुरू होती है । स्क्रिप्ट हर मिनट उठती है और इंटरनेट से प्राप्त सूर्योदय और सूर्यास्त के आधार पर लैपटॉप डिस्प्ले चमक सेट करती है। फुल ब्राइट और फुल डिम के बीच एक यूजर कॉन्फिगरेबल ट्रांजिशन फेज में हर मिनट में 3, 4, 5 या जो भी कैलकुलेट किया जाता है, उसकी वैल्यू बढ़ जाती है।

ओली ने संक्षेप pstreeमें उनके उत्तर को छुआ लेकिन इसे अस्वीकार कर दिया क्योंकि यह सभी sleepउदाहरणों को मार देगा । Pstree विकल्पों का उपयोग करके खोज को सीमित करके इससे बचा जा सकता है।

का उपयोग करते हुए pstree -hहम संपूर्ण उत्तराधिकार देखते हैं:

$ 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

जैसा कि आप देख सकते हैं कि एक सामान्य उबंटू लॉगिन में कई पीआईडी ​​(प्रोसेस आईडी) हैं।

हम इसका उपयोग करके अपनी चल रही स्क्रिप्ट तक सीमित कर सकते हैं:

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

हम देखते हैं:

  • cron एक खोल शुरू किया (प्रक्रिया आईडी 1308 और सत्र आईडी 1308)
  • शेल प्रक्रिया ID 1321 और सत्र ID 1308 (शेल से मेल खाते) के तहत चल रहे हमारे कार्यक्रम को कॉल करता है
  • हमारा प्रोग्राम sleepप्रक्रिया आईडी 26552 और फिर से सत्र आईडी 1308 के तहत कहता है

इस बिंदु पर हम उपयोग कर सकते हैं pkill -s 1308और यह पूरे सत्र को मार देगा जिसमें शेल, हमारे कार्यक्रम display-auto-brightnessऔर sleepकमांड शामिल हैं। इसके बजाय हम kill 26552अपने कार्यक्रम को जगाने और चमक को समायोजित करने के लिए केवल नींद की आज्ञा को मारने के लिए उपयोग करेंगे ।

आपके द्वारा देखे जाने वाले टर्मिनल में इसे मैन्युअल रूप से टाइप करना:

───────────────────────────────────────────────────────────────────────────────
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:~$ 

अगला कदम यह करना है जब लैपटॉप निलंबित से उठता है। उदाहरण के लिए जब ढक्कन बंद हुआ तो यह पूर्ण रूप से गहरा था और स्क्रीन की चमक "300" पर सेट थी। जब ढक्कन खोला जाता है तो यह दिन का प्रकाश होता है और चमक को "2000" पर सेट करने की आवश्यकता होती है। बेशक यह कार्यक्रम 1 से 59 सेकंड में खुद पर उठ जाएगा, लेकिन यह तुरंत सेट होने वाली चमक के लिए अधिक आरामदायक है।

यह लिखे जाने के बाद मैं सस्पेंड / रिज्यूम कोड पोस्ट करूंगा। उम्मीद है कि इस सप्ताह के अंत में।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.