मैं एक स्क्रिप्ट कैसे बना सकता हूं जो टर्मिनल विंडो खोलता है और उनमें कमांड निष्पादित करता है?

मेरे पास तीन स्क्रिप्ट हैं जिन्हें मुझे चलाने की आवश्यकता है जब मैं अपनी उबंटू मशीन शुरू करता हूं, तो वे मेरे विकास के माहौल में उपयोग की जाने वाली सेवाएं शुरू करते हैं ।

ऐसा करने के लिए, मैं मैन्युअल रूप से तीन टर्मिनल खोलता हूं और कमांड टाइप करता हूं ।

क्या स्क्रिप्ट बनाने का कोई तरीका है जो तीन टर्मिनल खोलेगा और इनमें से प्रत्येक में एक कमांड निष्पादित करेगा? (प्रत्येक कमांड एक अलग टर्मिनल विंडो में होना चाहिए ताकि मैं उनका आउटपुट देख सकूं) ।

gnome-terminal -- आदेश

या

xterm -e आदेश

या

konsole -e आदेश

बहुत ज्यादा

टर्मिनल -द आदेश

जब कमांड बाहर निकलता है तो टर्मिनल को रहने के लिए:

कंसोल में एक है --noclose झंडा।

एक्सटर्म में, एक है -hold झंडा।

में gnome-terminal, के लिए जाओ संपादित करें - &जीटी; प्रोफ़ाइल प्राथमिकताएं - &जीटी; शीर्षक. क्लिक करें आदेश टैब। का चयन करें टर्मिनल पकड़ो लेबल किए गए ड्रॉप-डाउन मेनू से जब कमांड बाहर निकलता है. आपको उसके लिए एक नया प्रोफ़ाइल बनाना चाहिए और इसके साथ निष्पादित करना चाहिए

सूक्ति-टर्मिनल -- विंडो-साथ-प्रोफ़ाइल=नामऑफप्रोफाइल -द आदेश

हार्ड-कोडिंग के बजाय gnome-terminal, konsole, वगैरह, विकल्प प्रणाली का उपयोग करें । डिफ़ॉल्ट टर्मिनल एमुलेटर निष्पादित करने वाला प्रोग्राम है:

x-terminal-emulator

मेरे सिस्टम पर, हर बार जब मैं इस कमांड को निष्पादित करता हूं तो यह कंसोल का एक नया उदाहरण खोलता है ।

सौभाग्य से, टर्मिनलों का समर्थन करने के लिए लगता है -e कमांड निष्पादित करने का विकल्प (मैंने इसके लिए सत्यापित किया है konsole और gnome-terminal). आदेश के बाद तर्क दिए गए आदेश को पारित कर दिया जाता है । बैश मेरे टर्मिनल में खुले रहने से इनकार करता है, टर्मिनल प्राप्त करने के लिए एक अतिरिक्त स्क्रिप्ट की आवश्यकता होती है:

#!/bin/sh"$@"exec "$SHELL"

यदि आपने पिछली स्क्रिप्ट को इस प्रकार सहेजा है /home/user/hacky और इसे निष्पादन योग्य बना दिया, आप अपनी स्क्रिप्ट चलाएंगे:

x-terminal-emulator -e /home/user/hacky your-script optional arguments here

पूर्ण पथ की आवश्यकता है और /home/user/hacky निष्पादन योग्य होना चाहिए ।

एक नई टर्मिनल विंडो में स्क्रिप्ट चलाने का मेरा पिछला प्रयास इसमें पाया जा सकता है संशोधन #2, इससे पहले कि मुझे एहसास हुआ कि तर्कों को पारित किया जा सकता है x-terminal-emulator.

अपडेट 17 फरवरी 2020: यह उत्तर अब शायद अप्रचलित है ।

इस लिंक पर क्लिक करने और इसके बजाय मेरे इस अन्य उत्तर का उपयोग करने पर विचार करें: कई टैब के साथ टर्मिनल खोलें और एप्लिकेशन निष्पादित करें


द्वारा सहायता प्राप्त निकगुलेटस्की का जवाब, और उनके जवाब के तहत मेरी अपनी टिप्पणी, और मेरी टिप्पणी के @ग्रैबेंटॉट के अपवोट से प्रेरित, यहां ऐसा करने का मेरा पसंदीदा तरीका है, खासकर जब मैं चाहता हूं कि टर्मिनल खुला रहे ताकि मैं मैन्युअल रूप से इसका उपयोग कर सकूं ।

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

यहाँ एक काल्पनिक उदाहरण है, जो एक एकल टैब खोलता है, इसे शीर्षक देता है और परीक्षण करता है, फिर सरल कमांड चलाता है cd /etc; ls इसके अंदर। द $SHELL अंत में भाग खोल को खुला रहने के लिए मजबूर करता है ताकि आप इसके आउटपुट को देख सकें और इसका उपयोग जारी रख सकें (मैंने इसे स्टैक ओवरफ्लो पर कहीं और सीखा):

gnome-terminal --tab --title="test" --command="bash -c 'cd /etc; ls; $SHELL'"

यहां एक अधिक जटिल उदाहरण दिया गया है जो एक ही गनोम-टर्मिनल में 3 अलग-अलग टैब खोलता है । यह ठीक उसी प्रकार की चीज है जो मेरा डेस्कटॉप शॉर्टकट करता है ताकि मैं एक ही बार में प्रोग्रामिंग विंडो का एक गुच्छा खोल सकूं:

gnome-terminal --tab --title="tab 1" --command="bash -c 'cd /etc; ls; $SHELL'" --tab --title="tab 2" --command="bash -c 'cd ~; ls; $SHELL'" --tab --title="tab 3" --command="bash -c 'cd ~/temp3; ls; $SHELL'"

यहाँ ऊपर उस आदेश का टूटना है:

  • gnome-terminal = एक सूक्ति-टर्मिनल खोलें
  • --tab = आगे क्या आता है के लिए एक अद्वितीय टैब खोलें
  • --title="tab 1" = इस टैब को शीर्षक दें &उद्धरण;टैब 1 & उद्धरण;
  • --command="bash -c 'cd /etc; ls; $SHELL'" = भागो bash -c 'cd /etc; ls; $SHELL' कमांड, जो एक कमांड है जिसे मैंने अभी एक उदाहरण के रूप में बनाया है; यहाँ यह क्या करता है:
  • bash -c कहते हैं कि यह एक बैश 'कॉमैंड' है
  • cd /etc = पथ में 'सी' बदलें ' डी ' डायरेक्टरी
  • ls = 'मैं इस निर्देशिका की सामग्री नहीं है
  • $SHELL = खोल को खुला रखने के लिए इस गुप्त टिडबिट की आवश्यकता होती है ताकि आप इसके साथ काम कर सकें । यदि आप शेल को खोलना चाहते हैं, तो अपना कमांड चलाएं, फिर बंद करें, बस इस हिस्से को हटा दें । हालांकि, मैं चाहता हूं कि टैब खुला रहे ताकि मैं प्रोग्रामिंग जादू कर सकूं । :)
  • हम तो पर वापस शुरू --tab टैब 2 का उत्पादन करने के लिए भाग, फिर टैब 3 के लिए । अपने दिल की सामग्री को अनुकूलित करें ।

स्क्रीनशॉट:

enter image description here

काफी बस-

#!/bin/bash/etc/init.d/ccpd status

यह अन्य आदेशों के लिए पर्याप्त है जिन्हें टर्मिनल में कुछ भी प्रदर्शित करने की आवश्यकता नहीं है । लेकिन यहां किसी को प्रदर्शित स्थिति को देखना होगा ।
तो, यह करने की जरूरत है टर्मिनल विंडो में चलाएं

#!/bin/bashgnome-terminal -e "/etc/init.d/ccpd status"  --window-with-profile=NAMEOFTHEPROFILE

अन्य पोस्ट इरादा [] प्लेसहोल्डर बनने के लिए

यहां" नेमऑफ्थेप्रोफाइल "को उस प्रोफ़ाइल के नाम से बदला जाना है जो"कमांड से बाहर निकलने पर टर्मिनल रखती है" ।

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

hacky_function(){"$@"exec "$SHELL"}

अपनी स्क्रिप्ट को "एक्स-टर्मिनल-एमुलेटर-ई /पथ/टू/स्क्रिप्ट हैकी_फंक्शन वैकल्पिक तर्कों के साथ यहां कॉल करें"

स्क्रिप्ट के अंत में "$ @ " डालना न भूलें

उपयोग करने के कारण होने वाली चेतावनियों से बचने के दौरान, मुझे इस तरह से कई टैब चेन करने पड़े --command, जिसे जल्द ही हटा दिया जाएगा:

gnome-terminal\    --tab\        --title="TAB 1" -- bash -c "cd ~; ls; $SHELL"gnome-terminal\    --tab\        --title="TAB 2" -- bash -c "cd ~/Desktop; ls; $SHELL"\

पार्टी के लिए लगभग एक दशक देर हो चुकी है, लेकिन यहां मेरा जवाब पायथन का उपयोग कर रहा है ।

में .gif नीचे मैंने स्क्रीन रिकॉर्डर के साथ एक मौजूदा टर्मिनल से प्रोग्राम लॉन्च किया, यह दिखाने के लिए कि यह लॉगिन पर कैसा दिखेगा:

dellstart.gif

मैंने इस उत्तर के लिए एक पायथन कार्यक्रम लिखा था । ओपी द्वारा अनुरोध नहीं की गई कुछ अतिरिक्त विशेषताएं हैं लेकिन मेरे लिए फायदेमंद हैं:

  • लॉगिन के बाद अक्सर उपयोग किए जाने वाले जीयूआई अनुप्रयोगों को सेटअप करने के लिए ऑटोस्टार्ट पर चलता है ।
  • एकाधिक खोलता है gnome-terminal टैब्स.
  • टर्मिनल टैब को शीर्षक असाइन करें ।
  • विंडोज़ को डेस्कटॉप पर पसंदीदा स्थान पर ले जाता है ।
  • खुलता है gedit और अंतिम पांच अलग-अलग टैब में फाइलें खोली गईं ।

पायथन कार्यक्रम:

#!/usr/bin/env python# -*- coding: utf-8 -*-#==============================================================================##       dellstart - Autostart GUI applications on Dell Fileserver##=============================================================================='''CALL:   dellstartREQUIRES:   sudo apt install xdotool    '''from __future__ import print_function           # Must be first importimport osimport timeBASHRC_TIME = 2                                 # Seconds to load ~/.bashrcWINDOW_TIME = .5                                # Secpmds fpr window to appearcommands = [ 'gnome-terminal &',                # Launch terminal in background             'sleep '+str(BASHRC_TIME),         # Bash command wait a sec             'move x y',                        # Move windows to x and/or y#             'move 2100 1000',                  # triple monitor setup             'xdotool type "cd ~"',             # Change to home directory             'xdotool key Return',              # Enter Key             'xdotool type "./ssh-activity"',   # Suspend after 15 minutes             'xdotool key Return',              # Enter Key             'title SSH\ Activity',             # Window title (escape spaces)             'xdotool key Control_L+Shift_L+T', # Open new terminal tab             'sleep '+str(BASHRC_TIME),         # Bash command wait a sec             'xdotool type "cd ~/askubuntu"',   # Change to working directory             'xdotool key Return',              # Enter Key             'title Ask\ Ubuntu',               # Window title (escape spaces)             'gedit',                           # Last 5 files will open up             'move x y',                        # Move windows to x and/or y#             'move 3849 2266',                  # triple monitor setup           ]""" NOTE: To discover window coordinates, arrange on desktop and type:        wmctrl -lG"""def process_commands(command_list):    for command in command_list:        if command.endswith('&'):            # Launch in background and get window ID opened            active_pid, active_win = launch_command(command)            if active_pid == 0:                print("ERROR launching", command, \                "Aborting 'dellstart' script")                exit()        elif command.startswith('move'):            move_window(command, active_win)        elif command.startswith('title'):            terminal_title(command)        elif command.startswith('gedit'):            gedit()        else:            run_and_wait(command)def launch_command(ext_name):    ''' Launch external command in background and return PID to parent.        Use for programs requiring more than .2 seconds to run.    '''    all_pids = get_pids(ext_name)       # Snapshot current PID list    all_wins = get_wins(all_pids)       # Snapshot of windows open    new_pids = all_pids    new_wins = all_wins    sleep_count = 0                     # Counter to prevent infinite loops    os.popen(ext_name)                  # Run command in background    while new_pids == all_pids:         # Loop until new PID is assigned        new_pids = get_pids(ext_name)   # Snapshot current PID list        if sleep_count > 0:             # Don't sleep first time through loop            time.sleep(.005)            # sleep 5 milliseconds        sleep_count += 1        if sleep_count == 1000:         # 10 second time-out            print('launch_ext_command() ERROR: max sleep count reached')            print('External command name:',ext_name)            return 0    pid_list = list(set(new_pids) - set(all_pids))    if not len(pid_list) == 1:        print('launch_command() ERROR: A new PID could not be found')        return 0, 0    time.sleep(WINDOW_TIME)             # Give time for window to appear    new_wins = get_wins(all_pids)       # Snapshot of windows open    win_list = list(set(new_wins) - set(all_wins))    if not len(win_list) == 1:        #print('launch_command() ERROR: New Window ID could not be found')        #suppress error message because we aren't using window ID at all        return int(pid_list[0]), 0    # Return PID of program we just launched in background    return int(pid_list[0]), int(win_list[0])def run_and_wait(ext_name):    ''' Launch external command and wait for it to end.        Use for programs requiring less than .2 seconds to run.    '''    result = os.popen(ext_name).read().strip()    #print('run_and_wait() command:', ext_name)    return resultdef get_pids(ext_name):    ''' Return list of PIDs for program name and arguments        Whitespace output is compressed to single space    '''    all_lines = []    # Just grep up to first space in command line. It was failing on !    prog_name = ext_name.split(' ',1)[0]    all_lines = os.popen("ps aux | grep -v grep | grep " + \                        "'" + prog_name + "'").read().strip().splitlines    PID = []    for l in all_lines():        l = ' '.join(l.split())         # Compress whitespace into single space        PID.append(int(l.split(' ', 2)[1]))    return PIDdef get_wins(all_pids):    ''' Return list of all windows open under PID list        Currently unncessary because we work on active window '''    windows = []    for pid in all_pids:        all_lines = os.popen('xdotool search --pid ' + str(pid)). \                             read().strip().splitlines        for l in all_lines():            windows.append(int(l))    return windowsdef move_window(line, active_win):    ''' Move window to x y coorindates on Desktop        If the letter x or y is passed, that dimension remains unchanged eg:            xdotool getactivewindow windowmove 100 100    # Moves to 100,100            xdotool getactivewindow windowmove x 100      # Moves to x,100            xdotool getactivewindow windowmove 100 y      # Moves to 100,y    '''    line = ' '.join(line.split())       # Compress whitespace to single space    x = line.split(' ')[-2]    y = line.split(' ')[-1]    # We don't need to pass window ID as last active window defaults    all_lines = os.popen('xdotool getactivewindow windowmove ' + x + ' ' + y). \                         read().strip().splitlines    for l in all_lines():        print(l)def terminal_title(new_title):    ''' Rather awkward calling xdotool which chokes on double quotes and bash        via python which chokes on backslashes.        Simple format (if it worked) would be:            command = r'PS1="${PS1/\\u@\\h: \\w/' + title + '}"'        The bash function copied from is:            function termtitle() { PS1="${PS1/\\u@\\h: \\w/$@}"; }        Reference for xdotool keycodes:         https://gitlab.com/cunidev/gestures/-/wikis/xdotool-list-of-key-codes    '''    title = new_title.split(' ', 1)[1]   # Strip out leading "title" token    command = 'xdotool type PS1='    run_and_wait(command)    run_and_wait('xdotool key quotedbl')    command = 'xdotool type $'    run_and_wait(command)    run_and_wait('xdotool key braceleft')    command = 'xdotool type PS1/'    run_and_wait(command)    run_and_wait('xdotool key backslash')    run_and_wait('xdotool key backslash')    command = 'xdotool type u@'    run_and_wait(command)    run_and_wait('xdotool key backslash')    run_and_wait('xdotool key backslash')    command = 'xdotool type "h: "'    run_and_wait(command)    run_and_wait('xdotool key backslash')    run_and_wait('xdotool key backslash')    command = 'xdotool type "w/"'    run_and_wait(command)    command = 'xdotool type "' + title + '"'    run_and_wait(command)    run_and_wait('xdotool key braceright')    run_and_wait('xdotool key quotedbl')    run_and_wait('xdotool key Return')def gedit():    last_modified_files = gedit_recent_files()    command = 'gedit '    for f in last_modified_files:        command=command+'"'        command=command+f        command=command+'" '    # Open gedit with last five modfied files    command=command+' &'    active_pid, active_win = launch_command(command)    if active_pid == 0:        print("ERROR launching", command, \        "Aborting 'dellstart' script")        exit()def gedit_recent_files():    ''' Get list of gedit 5 most recent files:    grep --no-group-separator -B5 'group>gedit' ~/.local/share/recently-used.xbel | sed -n 1~6p | sed 's#  <bookmark href="file:///#/#g' | sed 's/"//g'/home/rick/python/mmm added=2020-05-02T15:34:55Z modified=2020-11-19T00:43:45Z visited=2020-05-02T15:34:56Z>/home/rick/python/mserve added=2020-07-26T16:36:09Z modified=2020-11-28T01:57:19Z visited=2020-07-26T16:36:09Z>    '''    command = "grep --no-group-separator -B5 'group>gedit' " + \              "~/.local/share/recently-used.xbel | " + \              "sed -n 1~6p | sed 's#  <bookmark href=" + '"' + \              "file:///#/#g' | " + "sed 's/" + '"' + "//g'"    recent_files = []    times = []    all_lines = os.popen(command).read().strip().splitlines    uniquifier = 1                  # gedit can give all open files same time    for l in all_lines():        fname = l.split(' added=', 1)[0]        trailing = l.split(' added=', 1)[1]        modified = trailing.split(' modified=', 1)[1]        modified = modified.split('Z', 1)[0]        # TODO: 2038        d = time.strptime(modified, '%Y-%m-%dT%H:%M:%S')        epoch = time.mktime(d)        epoch = int(epoch)        recent_files.append(fname)        try:            times.index(epoch)            # gedit has given multiple files the same modification time            epoch += uniquifier            uniquifier += 1        except:            pass                    # Not a duplicate time        times.append(epoch)    N=5    top_files = []    if N > len(times):        # Less than 5 most recent files in list        N = len(times)        if N == 0:            # No most recent files in list            return top_files            # return empty list    # Store list in tmp to retrieve index    tmp=list(times)    # Sort list so that largest elements are on the far right    times.sort()    #print ('5 most recent from lists and indices')    for i in range(1, N+1):        top_files.append(recent_files[tmp.index(times[-i])])    return top_filesif __name__ == "__main__":    process_commands(commands)# end of dellstart

ध्यान दें कि आपको चर के साथ टिंकर करना पड़ सकता है BASHRC_TIME प्रोग्राम को तेजी से चलाने के लिए आपके सिस्टम पर । मेरे पास बहुत सारे कार्य चल रहे हैं ~/.bashrc और तुम्हारा बहुत तेज दौड़ सकता है ।

मैंने इसे कई वर्षों तक लिखने की योजना बनाई है, लेकिन अब तक इसके आसपास कभी नहीं मिला ।

का प्रयोग करें स्क्रीन कमांड और-डी मौजूदा स्क्रीन सत्र से अलग हो जाता है, और यहां फिर से जुड़ जाता है-एम एक नया स्क्रीन सत्र मजबूर करता है-डिफ़ॉल्ट नाम का उपयोग करने के बजाय एक नामित सत्र बनाता है

एक दशक बाद और मैंने एक नया जवाब जोड़ा है । कृपया मुझे सॉफ्टवेयर डेवलपर्स के लिए इसे बेहतर बनाने के लिए किसी भी बदलाव के बारे में बताएं ।