LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   [Bash] Send command to another terminal (https://www.linuxquestions.org/questions/linux-newbie-8/%5Bbash%5D-send-command-to-another-terminal-831313/)

ahtoot 09-10-2010 12:54 AM

[Bash] Send command to another terminal
 
I open up 2 xterms on my desktop, A(/dev/pts/0) and B(/dev/pts/1).

I can write from A to B using redirection e.g. echo "test" > /dev/pts/1

How do I run a command from A on B? e.g. "clear"


Basically I'm putting the 2 terminals side by side, and using terminal B to display the contents of the current working directory, by running the following in A:

export PROMPT_COMMAND="ls -a > /dev/pts/1"

but this fills up the screen pretty fast. I was actually looking for a way to clear up the second terminal.

Any advice? Thanks.

David the H. 09-10-2010 02:15 AM

I'm no expert, but I don't think there's any simple way to do that. > simply redirects the stdout of one process to the stdin of another. Since you're not placing anything into the readline of the terminal, it can't actually execute anything.

Perhaps it would be possible to write a simple script that would run on the receiving end, which would parse the incoming data before echoing it to the screen, and run the clear command whenever that input contains a specified string.

evo2 09-10-2010 02:26 AM

Named pipes!

Make a pipe:
Code:

mkfifo mypipe

Then on any two terminals:

In terminal A.
Code:

eval $(cat mypipe)
This should just "hang"

Then in terminal B.
Code:

echo "ls" > mypipe
At this point you should get a directory listing on terminal A.

You should be able to adapt this to your needs.

After you are done you can simply remove the named pipe with rm.

Cheers,

Evo2.

EricTRA 09-10-2010 02:32 AM

Hi,

evo2 beat me to this one, but here's a more complete description to add to his post.

Kind regards,

Eric

David the H. 09-10-2010 03:20 AM

Using evo2's named pipe suggestion, I whipped up this quick script. Any line fed into the pipe that begins with an @ symbol will be read as a command and executed. @exit will remove the pipe and exit the script. Everything else will be echoed straight to stdout. I set the pipe name to /tmp/catpipe by default, but you can easily change it.

Code:

#!/bin/bash

PIPE=/tmp/catpipe
trap "rm -f $PIPE" exit 1
[[ ! -p $PIPE ]] && mkfifo $PIPE

while true; do
    while read line; do
          case "$line" in
              @exit) rm -f $PIPE && exit 0;;
              @*) eval "${line#@}" ;;
              * ) echo "$line" ;;
          esac
    done <$PIPE
done

exit 2

Edit: Whaddyaknow, pretty much the same solution as in EricTRA's link. In fact, I've gone ahead and incorporated the trap command in my script too, to make sure it cleans up when force-terminating the loop.

ahtoot 09-10-2010 03:36 AM

Thanks, worked nicely

David the H. 09-10-2010 04:37 AM

Glad to hear it.

When you've decided that the solution is satisfactory, please mark the thread as solved and pass around a few thank-yous.


All times are GMT -5. The time now is 11:22 AM.