启动Ubuntu计算机时,我需要运行三个脚本,它们启动了开发环境中使用的服务。

为此,我手动打开三个终端并键入命令。 br />
是否可以创建一个脚本来打开三个终端并在每个终端中执行一个命令? (每个命令应在单独的终端窗口中,以便我可以看到其输出)。

评论

十年后,我添加了一个新答案。请让我知道为软件开发人员进行改进的任何调整。

#1 楼

gnome-terminal -- command
xterm -e command
konsole -e command


terminal -e command

在命令退出时使终端保​​持运行:
在konsole中,有一个--noclose标志。在xterm中,有一个-hold标志。
gnome-terminal中,请转到编辑->配置文件首选项->标题。单击命令选项卡。从标有“命令退出时”的下拉菜单中选择“保留终端”。您应该为此创建一个新的配置文件,并执行
gnome-terminal --window-with-profile=NAMEOFTHEPROFILE -e command


评论


如果尝试按住终端,则会收到“子进程正常退出,状态代码为127”

– Darshan Chaudhary
16年8月12日在7:49

gnome-terminal不再具有标题选项:(

–törzsmókus
17-2-22在13:04

@törzsmókus确实是2017年! LTS版本具有5年的支持寿命。 14.04直到2019年4月才结束。wiki.ubuntu.com/Releases

–bhass1
17 Mar 5 '17 at 22:33

gnome-terminal -e命令仅在命令加引号的情况下有效。因此,这不起作用:gnome-terminal -e“ echo hello world; sleep 3”,但它却有效:gnome-terminal -e“ bash -c'echo hello world; sleep 3'”。叹。

–更好
17年4月16日在19:47

考虑现在使用:gnome-terminal-命令

– dallonsi
19年7月1日在7:35



#2 楼

代替对gnome-terminalkonsole等进行硬编码,请使用Alternatives系统。执行默认终端仿真器的程序为:

x-terminal-emulator


在我的系统上,每次执行此命令时,它将打开Konsole的新实例。

幸运的是,终端似乎支持-e选项来执行命令(我已针对konsolegnome-terminal对其进行了验证)。命令后的参数传递给调用的命令。 Bash拒绝在我的终端机中保持打开状态,需要一个附加脚本来获得终端机: ,则可以使用以下脚本运行脚本:

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


需要完整路径,并且/home/user/hacky必须是可执行的。在版本2中可以在新的终端窗口中找到脚本,这是在我意识到可以将参数传递给/home/user/hacky之前。

评论


在这种情况下,这将无济于事,因为发问者想要对所有终端进行不同的操作。

– nickguletskii
2011年6月2日20:36

尝试#3:这应该保持终端打开并运行带有可选参数的程序。

– Lekensteyn
2011年6月2日21:06

我使用了gnome选项,但是一旦运行脚本,主终端就会关闭! ..知道为什么吗?

–麦克莱恩
2015年5月20日下午14:33

@ Suda.nese这是设计使然,当“终端”执行完脚本后,它将退出,因为没有更多要做。您可以通过调用可在其中执行命令(bash)的shell或“ read -p“按回车继续”行来“修复”此问题。

– Lekensteyn
2015年5月20日15:44

您如何在终端中运行多个命令?例如cd xxx && start.sh。解释器将&&视为命令的第二部分(这是逻辑上的),但是如果我引用它,则它将尝试将整个内容作为一个大参数执行

–理查德
17年5月25日在7:02



#3 楼

非常简单-

#!/bin/bash

/etc/init.d/ccpd status


这足以满足其他不需要在终端中显示任何内容的命令。但是这里必须看到显示的状态。
因此,它需要在终端窗口中运行。



此处“ NAMEOFTHEPROFILE”将替换为“命令退出时保留终端”的配置文件名称。





评论


我相信@cipricus []只是占位符

– Karthik T
13年1月23日在9:37

得到它了。但是我必须使终端不要关闭得这么快。我想这也是链接的问题

–user47206
13年1月23日在9:43

@cipricus您是否尝试过配置文件之一?只需将--window-with-profile = NAMEOFTHEPROFILE添加到我给的文件中

– Karthik T
13年1月23日在9:44

@cipricus我必须回到家才能给出更好的说明,但是这个想法是使用该选项集创建一个特殊的配置文件,并在上面的位置使用特殊配置文件的名称。

– Karthik T
13年1月23日在9:51

@cipricus如果这对您来说足够,那就可以了。配置文件仅是一组设置。您可以设置仅在脚本中使用的设置,而不必在所有终端中使用。您可以看到“编辑”->“配置文件”以查看您拥有的所有配置文件,然后在其中添加一个配置文件,如您所链接的文章中所述

– Karthik T
13年1月23日15:39

#4 楼

2020年2月17日更新:此答案现在已过时。

单击此链接并改用其他答案:打开带有多个选项卡的Terminal并执行应用程序。在@nickguletskii的回答以及他的回答下我自己的评论的帮助下,并受到@grabantot对我的评论的赞成,这是我的首选方法,尤其是当我希望终端保持打开状态以便可以手动使用它时。

例如。用法:这对添加到启动程序中非常有用,因此该脚本将运行,打开终端,在终端中创建并命名标签并为您运行命令。或者,您可以仅将此脚本的符号链接添加到桌面。我使用这种方法,因此我可以双击桌面上的单个图标,然后打开一堆终端(根据我要在其中进行的工作来命名各种标签)和程序来设置我的编程环境为日常工作提供了帮助。最后的cd /etc; ls部分迫使外壳保持打开状态,以便随后可以查看其输出并继续使用它(我在Stack Overflow上的其他地方了解到了这一点):

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


这是一个更复杂的示例,该示例在同一gnome终端中打开3个单独的选项卡。这正是我的桌面快捷方式所执行的操作,因此我可以一次打开一堆编程窗口:

br />


$SHELL =打开一个gnome终端

gnome-terminal =打开一个唯一的选项卡以显示下一步

--tab =将此标签的标题设置为“ tab 1”

--title="tab 1" =运行--command="bash -c 'cd /etc; ls; $SHELL'"命令,该命令是我作为示例编写的;它是做什么的:bash -c 'cd /etc; ls; $SHELL' ='c'hange'd'irectory进入“ / etc”路径

bash -c ='我不是该目录的内容

cd /etc =这个隐秘的小知识需要保持外壳打开,以便您可以使用它。如果要打开外壳,请运行命令,然后关闭,只需删除此部分。但是,我希望选项卡保持打开状态,以便使编程变得神奇。 :)


然后我们从ls部分重新开始,以生成选项卡2,然后再次生成选项卡3。



评论


很高兴为您提供帮助),我也有一些脚本,可以单击它们并开始从事该项目。它们有两个问题:许多终端窗口(它们有一个单独的屏幕)和例如在服务器崩溃后关闭的窗口。这个答案解决了--tab + $ SHELL的两个问题。好啊

–grabantot
18/12/31在9:33

我如何打开一个标签并将其设置为活动状态,此刻我先打开一个标签,然后还必须单击它才能使其成为活动标签

–阿尔法·布拉沃(Alfa Bravo)
20年8月21日在17:47

@AlfaBravo,不确定。您可能会考虑编写脚本来模拟实际的键盘按键,就像人类已经完成了一样。例如:xdotool key --clearmodifiers Super + d,就像我在show-desktop.desktop文件中使用的那样,按Windows Key + D可以切换显示桌面,就像人类进行了这些按键一样。我确信您可以只按脚本几次按Ctrl + PgUp或Ctrl + PgDn正确的次数来选择所需的标签,因为这是您可以人工切换标签的方式。

–加百利·斯台普斯
20年8月21日在18:01



#5 楼

对Lekensteyn的答案进行评论。您正在调用的脚本

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


使用“ x-terminal-emulator -e / path / to / script hacky_function可选参数在此处调用”脚本

别忘了在脚本的末尾加上“ $ @”

#6 楼

聚会晚了将近十年,但是,这是我使用Python的答案。
我为这个答案写了一个python程序。还有一些OP不需要的附加功能,但对我来说是有益的:

自动启动运行,以设置登录后经常使用的GUI应用程序。
打开多个.gif选项卡。
将标题分配给终端选项卡。
将窗口移至桌面上的首选位置。
在单独的选项卡中打开gnome-terminal和最后五个打开的文件。


 gedit 


注意,您可能必须对系统上的变量#!/usr/bin/env python # -*- coding: utf-8 -*- #============================================================================== # # dellstart - Autostart GUI applications on Dell Fileserver # #============================================================================== ''' CALL: dellstart REQUIRES: sudo apt install xdotool ''' from __future__ import print_function # Must be first import import os import time BASHRC_TIME = 2 # Seconds to load ~/.bashrc WINDOW_TIME = .5 # Secpmds fpr window to appear commands = [ '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 result def 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 PID def 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 windows def 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_files if __name__ == "__main__": process_commands(commands) # end of dellstart 进行修改,以使程序运行更快。我的BASHRC_TIME中有很多功能正在运行,您的功能可能运行得更快。

#7 楼

使用screen命令并
-d与现有的屏幕会话分离,然后在此处重新附加
-m强制新的屏幕会话
-S创建命名会话,而不使用默认名称

评论


这个答案根本不清楚,请注意使之更容易理解

–azerafati
17年4月20日在12:18

@azerafati的确,屏幕无法打开任何终端窗口...甚至那个超棒的包都不打算...

– m3nda
18年7月12日在19:55