Following this, one can very well make that last plan of yours work. For the command to-be-sent not to be processed by the shell, it has to be in the form of a string when reaches the pipe (thus echo "command"
, not echo `command`
). Then it has to be read by a background process (alike a daemon, but not necessarily) started in the appropriate terminal. It should be evaluated by the same process.
But it is boiler-platey to have a script per pipe. So let's generalize making a script as term-pipe-r.sh
(don't forget to chmod +x
it!):
#!/bin/bash
pipe=$1 # the pipe name is the first argument
trap 'rm -f "$pipe"' EXIT # ignore exit and delete messages until the end
if [[ ! -p $pipe ]]; then # if the pipe doesn't exist, create it
mkfifo $pipe
fi
while true # cycle eternally..
do
if read line <$ pipe; then
if [[ "$line" == 'close the term-pipe pipe' ]]; then
break
# if the pipe closing message is received, break the while cycle
fi
echo # a line break should be used because of the prompt
eval $line # run the line: as this script should be started
fi # in the target terminal,
done # the line will be run there.
echo "<pipe closing message>" # custom message on the end of the script
So say you want /dev/tty3
to receive commands: just go there, do
./term-pipe-r.sh tty3pipe & # $1 will be tty3pipe (in a new process)
And to send commands, from any terminal (even from itself):
echo "command" > tty3pipe
or to run a file there:
cat some-script.sh > tty3pipe
Note this piping ignores files like .bashrc
, and the aliases in there, such as alias ls='ls --color'
. Hope this helps someone out there.
Edit (note - advantage of non-daemon):
Above I talked about the pipe reader not being a daemon necessarily, but in fact, I checked the differences, and it turns out it is way better to be a mere background process in this case. Because this way, when you close the terminal, an EXIT
signal (SIGHUP
, SIGTERM
, or whatever) is received by the script as well, and the pipe is deleted then (see the line starting with trap
in the script) automatically, avoiding a useless process and file (and maybe others if there were such redirecting to the useless pipe).
Edit (automation):
Still, it is boring to have to run a script you (I, at least) probably want most of the time. So, let's automatize it! It should start in any terminal, and one thing all of them read is .bashrc
. Plus, it sucks to have to use ./term-pipe-r.sh
. So, one may do:
cd /bin # go to /bin, where Bash gets command names
ln -s /directory/of/term-pipe-r.sh tpr # call it tpr (terminal pipe reader)
Now to run it you'd only need tpr tty3pipe &
in /dev/tty3
whenever you'd want. But why do that when you can have it done automatically? So this should be added to .bashrc
. But wait: how will it know the pipe name? It can base the name on the TTY (which can be know with the tty
command), using simple REGEX's in sed
(and some tricks). What you should add to ~/.bashrc
will then be:
pipe="$(sed 's/\/dev\///' <<< `tty` | sed 's/\///')pipe"
# ^^^- take out '/dev/' and other '/', add 'pipe'
tpr $pipe & # start our script with the appropriate pipe name
Best Answer
It's the return character in the text you are copying that's triggering the automatic execution.
Let's take a different example, copy these lines all at once and paste them into your terminal:
If you look in your terminal, you will not see this:
You will see this (there may also be a line saying
World
):Instead of waiting for all the input to be pasted in, the first line executes (and for the same reason, the second line may or may not do so as well). This is because there is a
RETURN
character between the two lines.When you press the
ENTER
key on your keyboard, all you are doing is sending the character with the ASCII value of13
. That character is detected immediately by your terminal, and knows it has special instructions to execute what you have typed so far.When stored on your computer or printed on your screen, the
RETURN
character is just like any other letter of the alphabet, number, or symbol. This character can be deleted with backspace, or copied to the clipboard just like any other regular character.The only difference is, when your browser sees the character, it knows that instead of printing a visible character, it should treat it differently, and has special instructions to move the next set of text down to the next line. The
RETURN
character and theSPACE
character (ascii32
), along with a few other seldom used characters, are known as "non-printing characters" for this reason.Sometimes when you copy text from a website, it's difficult to copy only the text and not the return at the end (and is often made more difficult by the styling on the page).
Experiment time!
Below you will find two commands that will illustrate the problem, and that you can "practice" on. Start your cursor right before
echo
and drag until the highlight is right before the arrow:And now try the second command. Start your cursor right before
echo
and drag down until the cursor is on the second line, but is right in front of the<-
arrow. Copy it, and then paste it into your terminal:Depending on your browser, it may not even be visible that the text you selected went over two lines. But when you paste it into the terminal, you will find that it executes the line, because it found a
RETURN
character in the copied text.