अब से कुछ समय के लिए कुछ करें (और शायद कंसोल में परिणाम भी दिखाएं)


12

मैं उबंटू सर्वर 16.04 का उपयोग करता हूं और मैं atअपने वर्तमान सत्र में उपयोगिता का उपयोग करना चाहता हूं ताकि अब से 1 मिनट (कहो echo), एक विशिष्ट तिथि और समय दिए बिना - वर्तमान समय से सिर्फ 1 मिनट आगे।

यह विफल रहा:

echo 'hi' | at 1m

मेरे द्वारा चुने atजाने sleepका कारण यह है क्योंकि वर्तमान सत्र में नींद में बाधा आती है और किसी अन्य सत्र में आदेशों में देरी करने के लिए अधिक उपयुक्त है, बजाय इसके कि हम अधिकतर समय काम करते हैं। AFAIR, atइस तरह से व्यवहार नहीं करता है और मेरे सत्र में बाधा नहीं डालेगा।

Update_1

पाइड पाइपर के जवाब से, मैंने कोशिश की है:

(sleep 1m; echo 'hi')  &

मुझे इस पद्धति में एक समस्या है: "हाय" स्ट्रीम मेरे प्राथमिक प्रॉम्प्ट के अंदर प्रिंट की गई है और _इसमें जो प्राइमरी प्रॉम्प्ट शामिल है, उसके नीचे एक खाली सेकेंडरी प्रॉम्प्ट ( ) भी जुड़ता है, देखें:

USER@:~# (sleep 1m; echo 'hi')  &
[1] 22731
USER@:~# hi
^C
[1]+  Done

Update_2

पीटर कॉर्ड के जवाब से मैंने कोशिश की:

(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)

यह बाश 4.4 में ठीक से काम करता है, लेकिन कुछ पुराने संस्करणों में नहीं, प्रतीत होता है (उत्तर में टिप्पणियां देखें)। मैं व्यक्तिगत रूप से अपने स्वयं के वातावरण में बैश 4.3 का उपयोग करता हूं।


2
काश कि झंडे जीएनयू-स्टाइल होते और इसे फिर से व्यवस्थित किया जा सकता, तो यह "किल को मारना" जैसी आवाज़ नहीं होती!
एनएच।

जवाबों:


6

"ही" धारा मेरे प्रॉम्प्ट (इन stdin) में मुद्रित होती है और मेरे में नहींstdout

नहीं, यह "अपने में मुद्रित" नहीं हैstdin

यदि आप रिटर्न दबाते हैं, तो यह hiकमांड के रूप में चलने की कोशिश नहीं करेगा । यह सिर्फ इतना है कि आपके प्रॉम्प्ट के बाद कर्सर echoमुद्रित hiहोने पर पृष्ठभूमि में ।


शायद आप एक प्रमुख नईलाइन प्रिंट करना चाहते हैं , जैसे (sleep 1m && echo -e '\nhi' &)। ( echoअपने शेल के लिए आवश्यकतानुसार समायोजित करें। या printfपोर्टेबिलिटी के लिए उपयोग करें ।)

मैंने &पृष्ठभूमि के काम को "विघटित" करने के लिए अंदर को रखा , इसलिए आप "शोर" से भी बचते हैं [1]+ Done। साथ &&आदेशों के बीच, &पूरे परिसर कमान श्रृंखला पर लागू होता है तो यह सुरक्षा प्रॉम्प्ट सही करने के लिए के लिए इंतज़ार कर के दूर के बजाय रिटर्न sleepबाहर निकलने की तरह आप के साथ मिल चाहते हैं, उनके(sleep 1; echo ... &)

यहाँ क्या होता है (1 सेकंड की देरी के साथ):

peter@volta:~$ (sleep 1 && echo -e '\nhi' &)
peter@volta:~$ 
hi
       # cursor is at the start of this empty line.

बैश को पता नहीं है कि echoकुछ मुद्रित किया गया है, इसलिए यह नहीं जानता कि इसके संकेत को फिर से प्रिंट करने या स्क्रीन को साफ करने की आवश्यकता है। आप मैन्युअल रूप से ऐसा कर सकते हैं control-L

आप एक शेल फ़ंक्शन लिख सकते हैं जो खत्म होने के बाद अपने संकेत को फिर से प्रिंट करने के लिए बैश हो जाता हैecho । बस कर रहे हैं echo "$PS1"किसी भी पहले से ही टाइप अक्षरों को पुन: पेश नहीं करेगा। kill -WINCH $$मेरे सिस्टम पर स्क्रीन को साफ किए बिना अपनी प्रॉम्प्ट लाइन को फिर से प्रिंट करने के लिए बैश हो जाता है hi, प्रॉम्प्ट से पहले खुद से लाइन पर छोड़ देता है । SIGWINCH को स्वचालित रूप से भेजा जाता है, जब WINVA आकार के चेंजेस होते हैं, और बैश की प्रतिक्रिया उस पर होती है जो हम चाहते हैं।

यह अन्य गोले के साथ काम कर सकता है, लेकिन मैं इसे 100% पोर्टेबल / POSIX बनाने का प्रयास नहीं कर रहा हूं। ( दुर्भाग्य से, यह केवल bash4.4 पर काम करता है, bash4.3 पर नहीं, या कुछ सेटिंग पर निर्भर करता है जिससे मैं अनजान हूं )

  # bash4.4
peter@volta:~$ (sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
peter@volta:~$ ljlksjksajflasdf dfas      # typed in 2 seconds
hi
peter@volta:~$ ljlksjksajflasdf dfas      # reprinted by Bash because of `kill -WINCH`

आप इसे आसानी से एक शेल फ़ंक्शन में लपेट सकते हैं जो एक नींद आर्ग और एक संदेश लेता है।

Bash 4.3 SIGWINCH के बाद अपने संकेत को फिर से प्रिंट नहीं करता है, इसलिए यह वहां काम नहीं करता है। मैंने shopt -s checkwinsizeदोनों प्रणालियों पर सक्षम किया है, लेकिन यह केवल बैश 4.4 सिस्टम (आर्क लिनक्स) पर काम करता है।

यदि यह काम नहीं करता है, तो आप कोशिश कर सकते हैं (sleep 2 && echo -e '\nhi' && echo "$PS1" &), जो कमांड लाइन खाली होने पर "काम करता है"। (यह PROMPT_COMMANDसेट होने की संभावना को भी नजरअंदाज करता है।)


जब आप टाइमर पर आग लगाते हैं, तो टर्मिनल आउटपुट प्राप्त करने के लिए वास्तव में कोई भी साफ तरीका नहीं है जो आप अपने टर्मिनल पर कर सकते हैं। यदि आप किसी चीज़ को स्क्रॉल करने के बीच में हैं less, तो आप इसे आसानी से याद कर सकते हैं।

यदि आप इंटरेक्टिव परिणाम के साथ कुछ देख रहे हैं, तो मैं एक ऑडियो फ़ाइल चलाने का सुझाव देता हूं। जैसे कमांड-लाइन प्लेयर जैसे mpv(MPlayer2 का अच्छा कांटा)। या एक वीडियो फ़ाइल चुनें ताकि एक नई विंडो खुले।

(sleep 1 && mpv /f/share/music/.../foo.ogg </dev/null &>/dev/null &)

आप अपने echoनए xterm / konsole / gnome-टर्मिनल को खोलना चाह सकते हैं । एक विकल्प का उपयोग करें जो कमांड के बाहर निकलने के बाद टर्मिनल को खुला रखता है।


मैं आपको प्रिय डेविड का धन्यवाद करता हूं, और मैंने अंगूठा लगाया है। यह वास्तव में निकटतम है जो मुझे मिला है। क्या एक Enterमहत्वपूर्ण प्रेस ईवेंट का अनुकरण करने के लिए निम्न कमांड को अपग्रेड करने का एक तरीका है , सही प्रतिध्वनि प्रकट होने के बाद, इसलिए मुझे स्वचालित रूप से कंसोल के प्राथमिक प्रॉम्प्ट में वापस लाया जाएगा ? (sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
आर्कटिकोलिंग

@ आर्कटिकुलिंग: टर्मिनल में चल रहे शेल के संकेत को ताज़ा kill -WINCH $$ करता है । यह इसका उपयोग करने का पूरा बिंदु था। एंटर दबाने पर आंशिक रूप से टाइप की गई कमांड सबमिट होती है, लेकिन जैसा मैंने दिखाया, वैन्च नहीं करता। यदि आपने कुछ भी नहीं लिखा है, तो आपको एक खाली संकेत मिलता है।
पीटर कॉर्ड्स

1
यदि आपने लिखना शुरू कर दिया है rm -rf ~/some/directory, तो गलत समय पर दर्ज करें संभावित रूप से चलेगा rm -rf ~/। (सेफ्टी टिप: टाइपिंग के रास्ते खत्म करें और फिर कंट्रोल-ए और चेंज lsकरें rm -rf, ताकि फैट-फिंगरप्रिंटिंग किसी भी समय एंटर करें। आपका दिन नहीं चलेगा।)
पीटर कॉर्ड्स

वायर्ड, मैंने निष्पादित किया (sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)और प्रतिध्वनि दिखाई देने के बाद मुझे एक खाली प्रॉम्प्ट मिला, मारने के बाद ही Enterमैं प्राइमरी प्रॉम्प्ट पर वापस आ गया ... क्षमा करें यदि मैंने आपको गलत समझा, तो मैं बैश में काफी नया हूं।
आर्कटिकुलिंग

@ आर्कटिकुलिंग: मैं कोनसोल टर्मिनल एमुलेटर में आर्क लिनक्स पर बैश 4.4 का उपयोग कर रहा हूं। मुझे उम्मीद थी कि मेरी कमान कम से कम बाश के अन्य संस्करणों के लिए पोर्टेबल होगी, लेकिन शायद नहीं :( हाँ, बस एक screenसत्र में बश 4.3 में परीक्षण किया गया (और सिर्फ एसएसएच के माध्यम से) एक पुराने उबंटू प्रणाली पर, और मुझे आपके द्वारा वर्णित व्यवहार मिला।
पीटर कॉर्ड्स

13

उपयोग में सही है at <timespec>, <timespec>समय विनिर्देश कहां है। आप -fनिष्पादित करने के लिए कमांड वाले फ़ाइल को निर्दिष्ट करने के लिए विकल्प का उपयोग भी कर सकते हैं । यदि -fऔर कोई पुनर्निर्देशन का उपयोग नहीं किया जाता है, तो स्टैडेन (मानक इनपुट) से निष्पादित करने के लिए कमांड पढ़ेगा।

आपके उदाहरण में, "कुछ कमांड" को निष्पादित करने के लिए (मैंने नीचे के उदाहरण में "इको हाय" होने के लिए "कुछ कमांड" चुना) आपके द्वारा दर्ज किए गए हिट (अब) को हिट करने के एक मिनट बाद, जिसका <timespec>उपयोग करने का इरादा है now + 1 minute। तो, आप एक-लाइनर समाधान के साथ इच्छित परिणाम प्राप्त करने के लिए, कृपया नीचे दिए गए आदेश का उपयोग करें:

echo 'echo hi' | at now + 1 minute

यह माना जाता है (और करेंगे) echo hiएक मिनट के बाद कमांड चलाने के लिए । यहां समस्या यह है कि echo hiकमांड को डमी ट्टी में कमांड द्वारा निष्पादित किया जाएगा और आउटपुट को उपयोगकर्ता के मेल बॉक्स में भेजा जाएगा (यदि यह सही तरीके से कॉन्फ़िगर किया गया है - जिसमें मेल बॉक्स को कॉन्फ़िगर करने के तरीके पर अधिक व्यापक स्पष्टीकरण की आवश्यकता होती है एक यूनिक्स मशीन (इस प्रश्न के दायरे का हिस्सा नहीं है)। लब्बोलुआब यह है कि आप सीधे echo hiउसी टर्मिनल के परिणाम को देखने में सक्षम नहीं होंगे जो आपने कमांड जारी किया था। सबसे आसान विकल्प है कि आप इसे "कुछ फ़ाइल" पर पुनर्निर्देशित करें, उदाहरण के लिए:

echo 'echo hi > /tmp/at.out' | at now + 1 minute

उपरोक्त उदाहरण में, "कुछ फ़ाइल" है /tmp/at.outऔर अपेक्षित परिणाम यह है कि at.out/ tmp के तहत फ़ाइल एक मिनट के बाद बनाई गई है और पाठ 'हाय' का संदर्भ दें।

now + 1 minuteउपरोक्त उदाहरण के अलावा , कई अन्य विशिष्टताओं का उपयोग किया जा सकता है, यहां तक ​​कि कुछ जटिल भी। नीचे दिए गए उदाहरणों की तरह सुंदर मानव पठनीय लोगों की व्याख्या करने के लिए कमांड काफी स्मार्ट है:

now + 1 day, 13:25, mid‐night, noon, ...

कृपया संभव समय विनिर्देशों के बारे में अधिक जानकारी के लिए मैन पेज देखें क्योंकि संभव भिन्नताएं बहुत व्यापक हैं और इसमें दिनांक, रिश्तेदार या निरपेक्ष, आदि शामिल हो सकते हैं।


2
atडिफ़ॉल्ट रूप से मेल के माध्यम से आउटपुट भेजता है, लेकिन इसे ठीक से काम करने के लिए कॉन्फ़िगर करना होगा।
साइमन रिक्टर

मैं अब एक उत्तर के लिए 100 प्रतिनिधि इनाम की पेशकश करता हूं। कृपया नीचे दिए गए मेरे बाउंटी संदेश को पढ़ें at <timespec>और आपके द्वारा उपयोग किए गए ध्वज और ध्वज पर अधिक व्याख्या करने के लिए संपादित करें और यदि यह Ubuntu 16.04 xenial के अनुरूप है।
आर्कटिकुलिंग

ठीक है, मैंने उत्तर में विस्तार के स्तर को बढ़ा दिया है ताकि यह अब अधिक उपचारात्मक हो। यह कुछ के लिए थोड़ा लंबा-घुमावदार लग सकता है, लेकिन मेरा मानना ​​है कि यह संदेह के लिए कोई मार्जिन नहीं छोड़ता है क्योंकि यह स्पष्ट रूप से उदाहरण बताता है कि काम करते हैं और वे कैसे काम करते हैं।
मार्सेलो

7

sleepएक सब-टाइम में चलाएं :

(sleep 60; echo -e '\nhi')  &

नोट: लिनक्स पर आप सेकंड में या प्रत्यय s / m / h / d (सेकंड के लिए, मिनट, घंटे, दिन) के साथ सोने का तर्क दे सकते हैं। बीएसडी पर तर्क सेकंडों में होना चाहिए


मुझे इस पद्धति की एक छोटी सी समस्या है --- "हाय" धारा मेरे प्रॉम्प्ट (इन stdin) में छपी है और मेरे में नहीं stdout(जैसा कि यह एक नियमित रूप से होगा echo)।
आर्कटिकोलिंग

1
यदि आप अपने टर्मिनल में आउटपुट प्रॉम्प्ट और अन्य आदेशों के आउटपुट को नहीं चाहते हैं, तो आपको इसे कहीं और पुनर्निर्देशित करना होगा
PiedPiper

यह पुनर्निर्देशन @PiedPiper विफल हुआ (sleep 10s; echo 'hi') & 1>। मैं अब इस पर अधिक पढ़ता हूं।
आर्कटिकोलिंग

2
प्रलेखन पढ़ना हमेशा एक अच्छा विचार है :)
PiedPiper

1
यह @Arcticooling की तरह आप के अर्थ के बारे में उलझन में रहे हैं लगता है stdinऔर stdout। उन्हें कुछ नहीं करना है जहां चीजें आपके टर्मिनल पर दिखाई देती हैं; इसके बजाय, आपको उन्हें किसी विशेष प्रक्रिया (मूल रूप से, एक कार्यक्रम) के संबंध में व्याख्या करनी चाहिए । एक प्रक्रिया के लिए मानक इनपुट ("स्टडिन") एक स्रोत है जिससे प्रक्रिया डेटा पढ़ सकती है, और प्रक्रिया का मानक आउटपुट ("स्टडआउट") एक गंतव्य है, जिस पर वह डेटा लिख ​​सकता है। ये स्रोत और गंतव्य अन्य कार्यक्रम, या फाइलें या टर्मिनल हो सकते हैं (आपके द्वारा टाइप किया गया सामान स्टड पर जाता है, और जो कुछ भी स्टडआउट आता है वह प्रदर्शित होता है)।
डेविड जेड

3

यह विफल हो गया क्योंकि आप आउटपुट को पाइप कर रहे हैं echo "hi", जो कि बस के hiलिए है at, लेकिन atयह उम्मीद करता है कि यह इनपुट डिफ़ॉल्ट सिस्टम शेल द्वारा निष्पादित किया जा सकता है (आमतौर पर बैश, लेकिन कभी-कभी सिस्टम के आधार पर कुछ अलग होता है)।

इस:

at 1m << EOF
echo "hi"
EOF

आप जो करने की कोशिश करते दिखाई देंगे उसे प्राप्त करेंगे। यह एक शेल कंस्ट्रक्शन का उपयोग करता है जिसे 'यहाँ डॉक्यूमेंट' कहा जाता है, जो आम तौर पर इस प्रकार का काम करने के लिए स्वीकृत तरीका होता है (क्योंकि यह echoकमांड का उपयोग करने की तुलना में कई लाइनों को बेहतर तरीके से हैंडल करता है और इसके लिए आपको एक नई फाइल बनाने की आवश्यकता नहीं होती है, जैसे आपको इसकी आवश्यकता होगी cat), और उपयोग करने के लिए कुछ अधिक जटिल समकक्ष का अनुवाद करता है echo:

echo 'echo "hi"' | at 1m

यह संभवतः ध्यान देने योग्य है कि atकिसी भी कमांड-आउटपुट को उस उपयोगकर्ता को भेज देगा जो atकमांड को इनवाइट करता है, इसके बजाय टर्मिनल में आउटपुट को छेड़ने के बजाय sleepएक सब-डिले का उपयोग करते हुए कमांड में देरी होगी। विशेष रूप से, इसका मतलब है कि जब तक आपने सिस्टम का कुछ अनुकूलन नहीं किया है, या अपने स्थानीय मेल स्पूल को पढ़ने का इरादा है, तब तक आप कमांड के आउटपुट को चलाने में सक्षम नहीं होंगे at


किसी कारण से, दोनों उदाहरण आपने मुझे दिए हैं syntax error. Last token seen: m Garbled time । मुझे कोई जानकारी नहीं है की क्यों। मैं Ubuntu 16.04, बैश 4.0 का उपयोग करता हूं। हो सकता है कि आपने ऐसा दूसरे सिस्टम पर किया हो। यहां तक ​​कि जब मैं atबिना किसी और तर्क के बस टाइप करता हूं --- तब भी मुझे यही त्रुटि मिलती है। अधिक डेटा यहाँ
आर्कटिकोलिंग

1
at 1mसंगत के लिए काम नहीं करता है at। कमांड की आवश्यकता होगीat now + 1 minute
PiedPiper

@PiedPiper सही है, 1m POSIX के अनुरूप संस्करणों के साथ संगत नहीं है at, मैं सिर्फ यह मान रहा था कि आपके पास एक ऐसा संस्करण है जो उस वाक्यविन्यास को स्वीकार करता है।
ऑस्टिन हेमेलर्गरन

@PiedPiper, at 1mPOSIX नहीं है, लेकिन POSIX संगत कार्यान्वयन atइसे अपनी इच्छा के अनुसार व्याख्या करने के लिए स्वतंत्र हैं, यह एक atकार्यान्वयन को कम व्याख्यात्मक नहीं बनाता है क्योंकि यह एक महीने पहलेnow + 1 minute त्रुटि या अर्थ को वापस करने के समान है । IOW, यह कोड है जो POSIX नहीं है। at 1m
स्टीफन चेज़लस

2

@Peter Cordes का उत्तर और इस उत्तर को मिलाएं /programming/23125527/how-to-return-to-bash-prompt-after-printing-output-from-backgrounded-function/23125687#23125687

नीचे दिया गया कोड बाद के उत्तर से है, मेरा थोड़ा सा बदलाव है। इसे a.out (जो भी नाम आपको पसंद हो) दर्ज करने के लिए संकलित करें

#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
        char *tty = "/dev/tty";
        if (argc > 1)
                tty = argv[1];
        int fd = open(tty, O_WRONLY);

        int i;
        char buf[] = "\n";
        for (i = 0; i < sizeof buf - 1; i++)
                if (ioctl(fd, TIOCSTI, &buf[i]))
                        perror("ioctl");
        close(fd);
        return 0;
}

फिर नीचे कमांड चलाएं। (मैंने dir / tmp / में a.out डाला, आपको अपना बदलना पड़ सकता है)

(sleep 2 && echo -e '\nhi' && /tmp/a.out &)

या

(sleep 2 && echo -e '\nhi' && /tmp/a.out /proc/$$/fd/0 &)

BTW, kill -WINCH $$जेंटू पर बैश 4.3 के साथ मेरे लिए ठीक काम करता है।


1

ऊपर दिए गए उत्तरों के आधार पर, आप एम्बेडेड कमांड को अपने टर्मिनल पर सीधे निर्देशित कर सकते हैं, जैसे:

echo "echo hi >$(tty); kill -WINCH $$" | at now + 1 minute

ttyआदेश अपने वर्तमान टर्मिनल के उपकरण पथ देता है, उस में संलग्न $(...)बैश एक उप खोल में निष्पादित है, और मार कमांड मौजूदा प्रक्रिया होगा कि पार्टी अपने $ PS1 शीघ्र पुन: मुद्रित करने के लिए एक संकेत भेजता है।

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