如何使用已经在命令行中输入某些文本的方式启动终端?


25

除了让我重述我的问题外,让我向您介绍所需的用例:

我创建了一个简短的shell脚本来运行命令“ gnome-terminal --someoptionflagname'我要发布的文本'”,并执行此脚本。

Gnome终端弹出,出现命令行提示,后跟我的文字。

即: fields@mycomputer:/$ my text to be posted

能做到吗?


如果此错误已在Ubuntu中修复,则应检查cnee
ændrük

@ændrük,它是固定的,包装名称xnee现在是。
甜点,

Answers:


32

您可以使用Expectinstall)执行此操作。创建并执行~/bin/myprompt

#!/usr/bin/expect -f

# Get a Bash shell
spawn -noecho bash

# Wait for a prompt
expect "$ "

# Type something
send "my text to be posted"

# Hand over control to the user
interact

exit

并使用以下命令运行Gnome Terminal:

gnome-terminal -e ~/bin/myprompt

+1以使用Expect。多年来,我一直在使用它来帮助自动化许多事情。
Marco Ceppi

这很酷。我希望会有一些基于默认gnome-terminal功能的简单答案,但是看起来这可以解决问题。
emf 2010年

这个问题困扰了我很久了,我几乎不记得想要的用例是什么。因此,为了澄清起见:我想做类似“ gnome-terminal -e ls”的事情,但是要注意的是要保持窗口打开。因此,基本上是打开终端并运行Shell命令的快捷方式。与aendruk / msw的答案相比,这是否可以澄清问题?
emf 2010年

1
如果您只想让终端在执行命令后保持打开状态,则可以使用更简单的解决方案
ændrük

超级谢谢 我已经成功地将其集成到了一个称为Pentaho数据集成工具的shell脚本中。然后,我在11.10中将对该脚本的调用添加到Unity启动器中,它的工作原理就像一个超级按钮。
bioShark 2011年

8

如果我理解正确,那么您希望您的第一个输入行被预填充到在gnome-terminal命令行中传递的内容。

我不知道如何使用bash完全做到这一点,但是这很接近。在的~/.bashrc末尾添加以下行:

history -s "$BASH_INITIAL_COMMAND"

运行gnome-terminal -x env BASH_INITIAL_COMMAND='my text to be posted' bash,然后按Up提示重新调用文本。

还请注意,如果您set -o history在注释的末尾加上注释,则.bashrc它们将在bash开始时被输入到历史记录中,因此您可以通过将其移至Up关键点并删除首字母来将它们用作编辑的基础#


2
尽管不是我一直在寻找的解决方案,但它本身很有趣。
emf 2010年

8

ændrük的建议非常好并且对我有用,但是该命令在脚本中进行了硬编码,并且如果您调整终端窗口的大小,它将无法正常工作。我以他的代码为基础,添加了向命令提示命令发送myprompt脚本的功能,并且此脚本正确处理了终端窗口的大小调整。

#!/usr/bin/expect

#trap sigwinch and pass it to the child we spawned
#this allows the gnome-terminal window to be resized
trap {
 set rows [stty rows]
 set cols [stty columns]
 stty rows $rows columns $cols < $spawn_out(slave,name)
} WINCH

set arg1 [lindex $argv 0]

# Get a Bash shell
spawn -noecho bash

# Wait for a prompt
expect "$ "

# Type something
send $arg1

# Hand over control to the user
interact

exit

并使用以下命令运行Gnome Terminal:

gnome-terminal -e "~/bin/myprompt \"my text to be posted\""

1

ændrük的回答很好,但是对于这项任务来说可能有点沉重。

这是一个根据其参数编写脚本的脚本

#!/bin/sh
# terminal-plus-command: start a subordinate terminal which runs
# the interactive shell after first running the command arguments

tmpscript=/tmp/tmpscript.$$
echo "#!$SHELL" > $tmpscript
echo "$@" >> $tmpscript
echo exec "$SHELL" >> $tmpscript
chmod +x $tmpscript
gnome-terminal --command $tmpscript
rm -f $tmpscript

如果您没有做太多的Shell编程,那么这里的魔力似乎比它多。首先,我命名一个用于保存脚本的临时文件,其中$$是运行此脚本的Shell的进程ID。如果/tmp/something.$$此脚本的两个实例同时运行,则使用该隐喻,它们将不会尝试使用相同的临时文件。

该变量$SHELL设置为运行脚本的外壳的名称。如果使用/ usr / bin / bash,大概是您希望微型脚本也使用它。

"$@"是shell惯用语,用于“插入所有参数,并在需要时引用它们”。这种特殊的语法导致

script.sh 'my file' your\ file

将参数内插为两个元素

"my file" "your file"

而不是四个$@会产生

"my" "file" "your" "file"

该脚本的最后几行安排一个gnome-terminal开始运行迷你脚本,然后启动一个交互式shell。当gnome-terminal退出时,由于乱丢垃圾会删除临时脚本。

最后一行不是迷你脚本的一部分,它表明迷你脚本有效。如果上面的11行脚本位于名为rt.shchmod文件中,则使其可执行并随后执行。

$ chmod +x rt.sh && ./rt.sh echo hello world

所有这些的结果将是一个启动的gnome终端,显示

hello world

在其第一行,然后启动一个交互式shell:

msw@myhost:~$

我认为您的脚本可以简化为gnome-terminal -x sh -c "echo hello world; bash",但我认为这个问题并不是必需的。
ændrük

这看起来很酷。您能解释一下这里发生了什么吗?
emf 2010年

1
emfields:我为您添加了注释。
msw

1
你摇滚。感谢您的注释,这种帮助使脚本编写更容易进入
emf 2010年

0

我最喜欢解决此问题的两个答案是使用expect,在建议他们--init-file在shebang或执行终端时使用标志:

#!/bin/bash --init-file
commands to run

...并执行为:

xterm -e /path/to/script
# or
gnome-terminal -e /path/to/script
# or
the-terminal -e bash --init-file /path/to/script/with/no/shebang

expect (因为我将概述的原因)可能是更好的解决方案,除了我无法控制它是否已安装在目标环境中。

我遇到了bash --init-filegnome-terminals --command作为解决此问题的hack的问题是,shell在执行初始化脚本时无法访问STDIN。例如,如果我想运行某些需要用户输入的内容(例如ftp,telnet等),但随后又使父shell运行,它将无法正常工作;到目前为止,我所看到的唯一例外是ssh:

xterm -e /bin/bash --init-file <(echo 'ssh -X some-machine')

...但是我需要的比这个玩具示例还要复杂。无论如何,我希望这些--init-file内容对阅读此问题的任何人都有用。


-1

您可以使用-eor -x参数在新弹出的终端中运行命令,但这并不是您想要的。


关闭,但不是我想要的。对于这种情况,一个问题是终端在执行并完成后将立即关闭。因此,假设我想要“ ls〜/ notes”的快捷方式,它将在我查看输出之前关闭。
emf 2010年

如果有解决方案,它将解决我正在寻找的大多数情况。
emf 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.