macos 使用指定的命令(和自定义颜色)以编程方式启动 Terminal.app
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4404242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Programmatically launch Terminal.app with a specified command (and custom colors)
提问by dreeves
I can launch an xterm from the command line (or a program, via a system call) like so:
我可以从命令行(或程序,通过系统调用)启动一个 xterm,如下所示:
/usr/X11/bin/xterm -fg SkyBlue -bg black -e myscript
That will launch an xterm with blue text and a black background, and run an arbitrary script inside it.
这将启动一个带有蓝色文本和黑色背景的 xterm,并在其中运行任意脚本。
My question: How do I do the equivalent with Terminal.app?
我的问题:我如何使用 Terminal.app 做等效的事情?
采纳答案by David Moles
Assuming you already have the colors you want in one of your Terminal profiles, here's what I came up with (with some help from Juha's answerand from this Serverfault answer).
假设您已经在其中一个终端配置文件中拥有所需的颜色,这就是我想出的(在Juha 的回答和这个 Serverfault 回答的帮助下)。
Update:
更新:
On reflection, I think this echo
business is too complicated. It turns out you can use osascript
to make an executable AppleScript file with a shebang line:
仔细想想,我觉得这个echo
业务太复杂了。事实证明,您可以使用osascript
shebang 行制作一个可执行的 AppleScript 文件:
#!/usr/bin/osascript
on run argv
if length of argv is equal to 0
set command to ""
else
set command to item 1 of argv
end if
if length of argv is greater than 1
set profile to item 2 of argv
runWithProfile(command, profile)
else
runSimple(command)
end if
end run
on runSimple(command)
tell application "Terminal"
activate
set newTab to do script(command)
end tell
return newTab
end runSimple
on runWithProfile(command, profile)
set newTab to runSimple(command)
tell application "Terminal" to set current settings of newTab to (first settings set whose name is profile)
end runWithProfile
Save that as term.scpt
, make it executable with chmod +x
, and use it the same way as below, e.g. term.scpt "emacs -nw" "Red Sands"
.
将其另存为term.scpt
,使用 使其可执行chmod +x
,并使用与下面相同的方式,例如term.scpt "emacs -nw" "Red Sands"
。
Original answer:
原答案:
Assuming we save the script below as term.sh
...
假设我们将下面的脚本保存为term.sh
...
#!/bin/sh
echo '
on run argv
if length of argv is equal to 0
set command to ""
else
set command to item 1 of argv
end if
if length of argv is greater than 1
set profile to item 2 of argv
runWithProfile(command, profile)
else
runSimple(command)
end if
end run
on runSimple(command)
tell application "Terminal"
activate
set newTab to do script(command)
end tell
return newTab
end runSimple
on runWithProfile(command, profile)
set newTab to runSimple(command)
tell application "Terminal" to set current settings of newTab to (first settings set whose name is profile)
end runWithProfile
' | osascript - "$@" > /dev/null
...it can be invoked as follows:
...它可以调用如下:
term.sh
- opens a new terminal window, nothing special
term.sh COMMAND
- opens a new terminal window, executing the specified command. Commands with arguments can be enclosed in quotes, e.g.
term.sh "emacs -nw"
to open a new terminal and run (non-windowed) emacs
- opens a new terminal window, executing the specified command. Commands with arguments can be enclosed in quotes, e.g.
term.sh COMMAND PROFILE
- opens a new terminal window, executing the specified command, and sets it to the specified profile. Profiles with spaces in their names can be enclosed in quotes, e.g.
term.sh "emacs -nw" "Red Sands"
to open a new terminal and run (non-windowed) emacs with the Red Sands profile.
- opens a new terminal window, executing the specified command, and sets it to the specified profile. Profiles with spaces in their names can be enclosed in quotes, e.g.
term.sh
- 打开一个新的终端窗口,没什么特别的
term.sh COMMAND
- 打开一个新的终端窗口,执行指定的命令。带参数的命令可以用引号括起来,例如
term.sh "emacs -nw"
打开一个新终端并运行(非窗口化)emacs
- 打开一个新的终端窗口,执行指定的命令。带参数的命令可以用引号括起来,例如
term.sh COMMAND PROFILE
- 打开一个新的终端窗口,执行指定的命令,并将其设置为指定的配置文件。名称中带有空格的配置文件可以用引号括起来,例如
term.sh "emacs -nw" "Red Sands"
打开一个新终端并使用 Red Sands 配置文件运行(非窗口)emacs。
- 打开一个新的终端窗口,执行指定的命令,并将其设置为指定的配置文件。名称中带有空格的配置文件可以用引号括起来,例如
If you invoke it with a bad command name, it'll still open the window and set the profile, but you'll get bash's error message in the new window.
如果您使用错误的命令名称调用它,它仍会打开窗口并设置配置文件,但您将在新窗口中收到 bash 的错误消息。
If you invoke it with a bad profile name, the window will still open and the command will still execute but the window will stick with the default profile and you'll get an error message (to stderr wherever you launched it) along the lines of
如果您使用错误的配置文件名称调用它,该窗口仍将打开并且该命令仍将执行,但该窗口将坚持使用默认配置文件,并且您将收到一条错误消息(在您启动它的任何地方发送到 stderr)
525:601: execution error: Terminal got an error: Can't get settings set 1 whose name = "elvis". Invalid index. (-1719)
525:601:执行错误:终端出错:无法获取名称 =“elvis”的设置集 1。索引无效。(-1719)
The invocation is slightly hacky, and could probably be improved if I took the time to learn getopt
(e.g., something like term.sh -p profile -e command
would be better and would, for instance, allow you to easily open a new terminal in the specified profile without invoking a command). And I also wouldn't be surprised if there are ways to screw it up with complex quoting. But it works for most purposes.
调用有点麻烦,如果我花时间学习可能会改进getopt
(例如,类似的东西term.sh -p profile -e command
会更好,例如,允许您轻松地在指定的配置文件中打开一个新终端而无需调用命令)。如果有办法用复杂的引用把它搞砸,我也不会感到惊讶。但它适用于大多数目的。
回答by Sam Deane
You can open an app by bundle id too, and give other parameters.
您也可以通过 bundle id 打开应用程序,并提供其他参数。
If there's an executable script test.sh in the current directory, the following command will open and run it in Terminal.app
如果当前目录下有可执行脚本 test.sh,下面的命令会在 Terminal.app 中打开并运行
open -b com.apple.terminal test.sh
The only down side that I can find is that Terminal doesn't appear to inherit your current environment, so you'll have to arrange another way to pass parameters through to the script that you want to run. I guess building the script on the fly to embed the parameters would be one approach (taking into account the security implications of course...)
我能找到的唯一缺点是终端似乎没有继承您当前的环境,因此您必须安排另一种方式将参数传递给您要运行的脚本。我想即时构建脚本以嵌入参数将是一种方法(当然要考虑到安全隐患......)
回答by Juha
Almost all (every?) osx program can be launched from command line using:
几乎所有(每个?)osx 程序都可以使用以下命令从命令行启动:
appName.app/Contents/MacOS/command
appName.app/Contents/MacOS/command
For terminal the command is:
对于终端,命令是:
/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal
/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal
You can use the autocomplete (tab) or ls to find the correct filenames. ".app" is basically a folder.
您可以使用自动完成(选项卡)或 ls 来查找正确的文件名。“.app”基本上是一个文件夹。
To change the colors and run a script... I think you cannot do it with shell scripts as Terminal does not accept arguments ("Terminal myScript.sh" does not launch myScript). With iTerm this works.
要更改颜色并运行脚本...我认为您不能使用 shell 脚本来执行此操作,因为终端不接受参数(“终端 myScript.sh”不启动 myScript)。使用 iTerm 这有效。
Workaround is to use applescript (wrapped in a shell script):
解决方法是使用 applescript(封装在 shell 脚本中):
#!/bin/sh
osascript -e '
tell application "Terminal"
activate
tell window 1
do script "sleep 5; exit"
set background color to {0, 11111, 11111}
set win_id to id
end tell
set w_ids to (id of every window)
repeat while w_ids contains win_id
delay 1
set w_ids to (id of every window)
end repeat
end tell'
Ok, now it should behave exactly the same as the xterm example. The drawback is the constant polling of the window ids (which is bad programming).
好的,现在它的行为应该与 xterm 示例完全相同。缺点是窗口 id 的不断轮询(这是糟糕的编程)。
edit:A bit more elegant applescript would use the 'busy' property of Terminal. I will leave the original code as is works for a general program (not just terminal).
编辑:更优雅的applescript 将使用终端的'busy' 属性。我将保留原始代码原样适用于一般程序(不仅仅是终端)。
tell application "Terminal"
tell window 1
do script "sleep 2"
set background color to {0, 11111, 11111}
repeat while busy
delay 1
end repeat
close
end tell
end tell
Also for perfectly correct program, one should check that whether the terminal is running or not. It affects the number of windows opened. So, this should be run first (again a nasty looking hack, that I will edit later as I find a workingsolution).
同样对于完全正确的程序,应该检查终端是否正在运行。它会影响打开的窗口数量。所以,这应该首先运行(这又是一个看起来很讨厌的黑客,我稍后会在找到可行的解决方案时进行编辑)。
tell application "System Events"
if (count (processes whose name is "Terminal")) is 0 then
tell application "Terminal"
tell window 1
close
end tell
end tell
end if
end tell
br,
Juha
br,
朱哈
回答by jerseyboy
You can also go into terminal GUI, completely configure the options to your heart's content, and export them to a ".terminal" file, and/or group the configurations into a Window Group and export that to a terminal file "myGroup.terminal". Then
您还可以进入终端 GUI,根据您的喜好完全配置选项,并将它们导出到“.terminal”文件,和/或将配置分组到一个窗口组中并将其导出到终端文件“myGroup.terminal” . 然后
open myGroup.terminal
打开 myGroup.terminal
will open the terminal(s) at once, with all your settings and startup commands as configured.
将立即打开终端,其中包含您配置的所有设置和启动命令。
回答by jhuebsch
you can launch terminal with the following command, not sure how to specify colors:
您可以使用以下命令启动终端,但不确定如何指定颜色:
open /Applications/Utilities/Terminal.app/
回答by djb
The answer from @david-moles above works but run the terminal and command in ~ rather the current working directory where term was launched. This variation adds a cd command.
上面来自@david-moles 的答案有效,但在 ~ 而不是启动 term 的当前工作目录中运行终端和命令。此变体添加了 cd 命令。
#!/usr/bin/env bash
# based on answer by @david-moles in
# https://stackoverflow.com/questions/4404242/programmatically-launch-terminal-app-with-a-specified-command-and-custom-colors
echo "
on run argv
if length of argv is equal to 0
set command to \"\"
else
set command to item 1 of argv
end if
set command to \"cd '"$PWD"' ;\" & command
if length of argv is greater than 1
set profile to item 2 of argv
runWithProfile(command, profile)
else
runSimple(command)
end if
end run
on runSimple(command)
tell application \"Terminal\"
activate
set newTab to do script(command)
end tell
return newTab
end runSimple
on runWithProfile(command, profile)
set newTab to runSimple(command)
tell application \"Terminal\" to set current settings of newTab to (first settings set whose name is profile)
end runWithProfile
" | osascript - "$@" > /dev/null
There may be a way to set PWD this with applescript.
可能有一种方法可以使用 applescript 设置 PWD。
Note: When I use this, I sometimes two Terminal windows, one a shell running in ~ and a second which runs the cd command and command from argv[1]. Seems to happen if Terminal is not already running; perhaps it is opening old state (even tho I had no open terminals when I closed it).
注意:当我使用它时,我有时会出现两个终端窗口,一个是在 ~ 中运行的 shell,另一个是从 argv[1] 运行 cd 命令和命令。如果终端尚未运行,似乎会发生;也许它正在打开旧状态(即使我关闭它时没有打开的终端)。