31

Rather than rephrasing my question, let me describe to you the desired user-case:

I create a short shell-script to run command "gnome-terminal --someoptionflagname 'my text to be posted'", and execute this script.

Gnome-terminal pops up, with command-line prompt followed by my text.

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

Can this be done?

2
  • If this bug is ever fixed in Ubuntu you should look into cnee.
    – ændrük
    Oct 8, 2010 at 19:46
  • @ændrük It's fixed and the package name is xnee now.
    – dessert
    Sep 12, 2017 at 7:20

7 Answers 7

33

You can do this with expect (install). Create and make executable ~/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

and run Gnome Terminal with:

gnome-terminal -e ~/bin/myprompt
6
  • +1 for using Expect. I've used this for years to help automate a lot of things. Oct 9, 2010 at 0:42
  • This is cool. I was hoping there would be some simple(ish) answer based on default gnome-terminal functionality, but looks like this answers the job.
    – emf
    Oct 10, 2010 at 2:38
  • This one has been bugging me so long, I almost couldn't remember what the intended use-case was. So, for clarification: I would want to do something like "gnome-terminal -e ls", but the catch is to have the window remain open. So, basically shortcuts to opening a terminal and running shell commands. Does this clarify issues vs aendruk/msw's answers?
    – emf
    Oct 10, 2010 at 2:47
  • 1
    If all you want is the terminal to remain open after a command, there are much simpler solutions.
    – ændrük
    Oct 10, 2010 at 3:21
  • Super, thanks. I've successfully integrated this into a shell script that call calls Pentaho data integration tool. Then I've added the call to this script to Unity launcher in 11.10, and it works like a charm.
    – bioShark
    Dec 2, 2011 at 2:17
9

ændrük's suggestion is very good and worked for me, however the command is hardcoded within the script, and if you resize the terminal window it doesn't work well. Using his code as the base, I've added the ability to send the myprompt script the command as an argument, and this script correctly handles resizing the terminal window.

#!/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

and run Gnome Terminal with:

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

If I understand correctly, you want your first input line to be prefilled to contents that you pass on the gnome-terminal command line.

I don't know how to do exactly this with bash, but here's something that comes close. In your ~/.bashrc, add the following line at the very end:

history -s "$BASH_INITIAL_COMMAND"

Run gnome-terminal -x env BASH_INITIAL_COMMAND='my text to be posted' bash, and press Up at the prompt to recall the text.

Note also that if you put set -o history followed by comments at the end of your .bashrc, they will be entered into the history as bash starts, so you can use them as a basis for editing by reaching them with the Up key and removing the initial #.

1
  • 2
    Though not quite the solution I was looking for, this is interesting in its own right.
    – emf
    Oct 10, 2010 at 2:39
1

ændrük's answer is fine, but perhaps a little heavyweight for the task.

Here is a script that writes a script based on its arguments

#!/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

If you've not done much shell programming, there appears to be more magic here than there is. First, I name a temporary file for holding the script where $$ is the process ID of the shell running this script. The /tmp/something.$$ metaphor is used in case two instances of this script are run at the same time, they won't try to use the same temporary file.

The variable $SHELL is set to the name of the shell running the script. If you use /usr/bin/bash, presumably you'd like the mini-script to use it also.

The "$@" is a shell idiom for "interpolate all my arguments, quoting them if needed". This peculiar syntax causes

script.sh 'my file' your\ file

to interpolate the arguments as two elements

"my file" "your file"

instead of the four that $@ would yield

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

The last lines of the script arrange for a gnome-terminal to start running the mini-script and then starting an interactive shell. When the gnome-terminal exits, the temporary script is removed because littering is uncool.

The last line is not a part of the mini-script, it demonstrates that the mini-script works. If the 11 line script above is in a file called rt.sh then the chmod makes it executable and then it is executed.

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

The result of all of this will be a gnome terminal which starts up, displays

hello world

on its first line and then starts an interactive shell:

msw@myhost:~$
4
  • I think your script could be reduced to gnome-terminal -x sh -c "echo hello world; bash", which I don't think the question is asking for.
    – ændrük
    Oct 9, 2010 at 22:13
  • This looks cool. Can you explain what is happening here?
    – emf
    Oct 10, 2010 at 2:38
  • 1
    e.m.fields: I annotated it for you.
    – msw
    Oct 10, 2010 at 4:35
  • 1
    you rock. thanks for the annotations, this kind of help makes barrier-to-entry with scripting much more accessible
    – emf
    Oct 11, 2010 at 4:41
0

The two answers I've liked best to solve this are using expect and this one where they recommend using the --init-file flag either in the shebang or when executing the terminal:

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

... and execute it as:

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 is probably the better solution (for reasons I'll outline), except that I cannot control whether it's installed in my target environment.

The problem I ran into with bash's --init-file and gnome-terminal's --command as a hack to solve this is the shell doesn't have access to STDIN while executing init scripts. If, for example, I want to run something that would require user input (ftp, telnet, etc) but leave the parent shell running afterward it won't work; the only exception I've seen to this so far is ssh:

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

... but what I need is more complicated than this toy example. Anyway, I hope the --init-file stuff is useful to anyone reading this question.

0

To start in interactive bash inside a gnome-terminal with some commands already executed I put those commands in a setup file and dynamically append the contents to my .bashrc file:

# my_startup_script.sh
export FOO=bar
echo "hello world"
gnome-terminal --tab -- bash -c "bash --rcfile <(cat ${HOME}/.bashrc my_startup_script.sh; )"
=> 
hello world
$ echo $FOO
bar
-1

You can use the -e or -x arguments to run a command inside a newly popped up terminal, but that's not exactly what you want.

2
  • close, but not quite what I'm looking for. One problem, for this case, is that when executed and finished, the terminal will immediately close. So, let's say I want a shortcut to "ls ~/notes", it will close before I can view the output.
    – emf
    Oct 10, 2010 at 2:41
  • If there was a solution to this, it would solve most of the cases I'm looking for.
    – emf
    Oct 10, 2010 at 2:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .