allocate a tie between a job and a terminal - bash

How can I allocate a tie to the currently open terminal?
Sorry - to make clear:
As I mention in this question
https://superuser.com/questions/575847/kill-running-script-i-think-i-must-allocate-terminal
I am having trouble when I run commands on a another machine using ssh and here-doc. i.e.
ssh another_machine << 'ENDSSH' commands/script-to-run ENDSSH
but I get this message:
Pseudo-terminal will not be allocated because stdin is not a terminal.
This creates a problem that being now the job/process cannot be detected/killed with ps/job commands.
Can I tie the job to a currently open terminal or new terminal window?
Thanks a lot!
FYI:
I am using the other question (linked above) only as one example of when I need to allocate a tie. I expect others to appear.

Try giving ssh the -t option, which forces it to create a pseudo-terminal.

Related

How to send input to a console/CLI program running on remote host using bash?

I have a script that I normally launch using the following syntax:
ssh -Yq user#host "xterm -e '. /home/user/bin/prog1 $arg1;prog2'"
(note: I've removed some of the complexities of the command, so please excuse if there are any syntax errors in the ssh command; it should not be relevant to the question)
This launches an xterm window that runs prog1, and after completion runs prog2. prog2 is a console-style program that performs some setup, then several seconds later waits for user input.
Is there a way via bash script (preferably without downloading external packages) that I can send data to prog2 that's running on $host?
I've looked into << and expect, but it's way over my head. My intuition is that there's probably a straightforward way of doing this, but I can't figure out what terms to search for. I also understand that I can remotely send keystrokes to a host using xdotools or something similar, but I'm hesitant to request a new package installation unless I know that's the only reasonable solution.
Thanks!

bash ignores & for last command in loop

I just wrote my first bash script to start some redis instances on a development server. While it is mostly working, the last opened redis instance is blocking the active terminal – though I have the trailing & sign and the other started instances aren't blocking the terminal. How would I push them all to the background?
Here's the script:
#!/bin/bash
REDIS=(6379 6380 6381 6382 6383 6390 6391 6392 6393)
for i in "${REDIS[#]}"
do
:
redis-server --port $i &
done
It sounds like your terminal is not actually blocked, your prompt just got overwritten. It's a purely cosmetic issue. Due to the way terminals work, bash doesn't know to redraw it so it looks like the command is in the foreground.
Run the script again, and blindly type lsEnter. You'll probably see that the shell responds as normal, even though you can't see the prompt.
You can alternatively just hit Enter to get bash to redraw the prompt.

How to ssh into a shell and run a script and leave myself at the prompt

I am using elastic map reduce from Amazon. I am sshing into hadoop master node and executing a script like.
$EMR_BIN/elastic-mapreduce --jobflow $JOBFLOW --ssh < hivescript.sh . It sshes me into the master node and runs the hive script. The hivescript contains the following lines
hive
add jar joda-time-1.6.jar;
add jar EmrHiveUtils-1.2.jar;
and some commands to create hive tables. The script runs fine and creates the hive tables and everything else, but comes back to the prompt from where I ran the script. How do I leave it sshed into hadoop master node at the hive prompt.
Consider using Expect, then you could do something along these lines and interact at the end:
/usr/bin/expect <<EOF
spawn ssh ... YourHost
expect "password"
send "password\n"
send javastuff
interact
EOF
These are the most common answers I've seen (with the drawbacks I ran into with them):
Use expect
This is probably the most well rounded solution for most people
I cannot control whether expect is installed in my target environments
Just to try this out anyway, I put together a simple expect script to ssh to a remote machine, send a simple command, and turn control over to the user. There was a long delay before the prompt showed up, and after fiddling with it with little success I decided to move on for the time being.
Eventually I came back to this as the final solution after realizing I had violated one of the 3 virtues of a good programmer -- false impatience.
Use screen / tmux to start the shell, then inject commands from an external process.
This works ok, but if the terminal window dies it leaves a screen/tmux instance hanging around. I could certainly try to come up with a way to just re-attach to prior instances or kill them; screen (and probably tmux) can make it die instead of auto-detaching, but I didn't fiddle with it.
If using gnome-terminal, use its -x or --command flag (I'm guessing xterm and others have similar options)
I'll go into more detail on problems I had with this on #4
Make a bash script with #!/bin/bash --init-file as the shebang; this will cause your script to execute, then leave an interactive shell running afterward
This and #3 had issues with some programs that required user interaction before the shell is presented to them. Some programs (like ssh) it worked fine with, others (telnet, vxsim) presented a prompt but no text was passed along to the program; only ctrl characters like ^C.
Do something like this: xterm -e 'commands; here; exec bash'. This will cause it to create an interactive shell after your commands execute.
This is fine as long as the user doesn't attempt to interrupt with ^C before the last command executes.
Currently, the only thing I've found that gives me the behavior I need is to use cmdtool from the OpenWin project.
/usr/openwin/bin/cmdtool -I 'commands; here'
# or
/usr/openwin/bin/cmdtool -I 'commands; here' /bin/bash --norc
The resulting terminal injects the list of commands passed with -I to the program executed (no parms means default shell), so those commands show up in that shell's history.
What I don't like is that the terminal cmdtool provides feels so clunky ... but alas.

Automate an application using scripting, managing multiple terminals

I am new to Ubuntu and Bash scripting. I am working on a project to give a demo on an SDN application to my class. I need some help in scripting to create the demo. Please help in case if you have any idea on what am asking.
The demo uses a tool called mininet. I need just one script so that I can automate the whole of my demo.
The commands I need to run are given in order below.
Run "sudo mn" on the terminal. This changes the prompt from
/mininet$ sudo mn
to
mininet>
Now on this terminal where the prompt is mininet>, I need to run xterm h1 followed by xterm h2 to create separate terminals for two hosts created by mininet.
I have to access the xterm terminal for h1 and run a command there . eg: ifconfig
I have to access the xterm terminal for h2 and run a command there . eg : set ip address
I have to run a ping in xterm terminal for h1 and while this is happening, i want to access terminals of h2 and start a ping in xterm terminals of h2.
I have to go back to the previous terminal from where the xterm terminals were spawned. mininet> prompt one. and run exit and then when the prompt goes back to normal /mininet$ i have to sudo mn -c.
All of this should be done from one script. Please ignore the specific commands mentioned and give a generic solution or clues.

How to run a process in the background inside Gvim?

Well, what I need to do actually is CTRL-Z out of a process that got started from insert mode in GVim.
My command :Cdprun executes cdprun.sh which runs a sudo-ed daemon. I can add & at the end of the sudo-ed daemon call to run in the background and that works but the user doesn't get prompted for a password. Instead I want to just CTRL-Z out of it but the keyboard interrupt doesn't work. Any ideas? Thx.
You generally have two options in this case: generic is using something like vim-addon-async mentioned by #Nicalas Martin or vim with built-in interpreters support: tcl with expect module, python with pyexpect, perl with Expect, maybe something else (note: all of the mentioned packages are not shipped with tcl/python/perl). Second is specific to current situation: it is backgrounding in the other place. From your explanation I guessed that you have a script looking like
#!/bin/sh
<...>
sudo run-daemon --daemon-args # Last executed line
, am I right? Than you can just put backgrounding in another place: not
sudo run-daemon --daemon-args &
, but
sudo sh -c "nohup run-daemon --daemon-args &"
Here is a script to deal with asynchronous command in vim. Not a perfect solution but could be a good temporary solution. http://www.vim.org/scripts/script.php?script_id=3307

Resources