How to send data to previous program (pipe)?


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting How to send data to previous program (pipe)?
# 8  
Old 02-05-2018
You can achieve this using shell coprocesses

There are examples on this forum and online.
I found one done example by doing sqlplus cooprocess ksh search in google.

Regards
Peasant.
This User Gave Thanks to Peasant For This Post:
# 9  
Old 02-05-2018
There's one big pitfall with this: Which program is reading when? It will be very easy to end up in a deadlock with both programs waiting for the other.

So, this is not nearly as simple as it appears, and why Expect is so valuable when it's really needed.
This User Gave Thanks to Corona688 For This Post:
# 10  
Old 02-07-2018
Quote:
Originally Posted by Peasant
You can achieve this using shell coprocesses

There are examples on this forum and online.
I found one done example by doing sqlplus cooprocess ksh search in google.

Regards
Peasant.
I didn't know about coprocesses before. In my case, I think, writing a parser with coprocesses is not needed and too complicated (for such a small requirement).

Is it possible to do a redirection to a process by it's PID? For example:
Code:
$ echo "something" > PID#

Quote:
Originally Posted by Don Cragun
Send email to yourself, send a message to a message queue, write to a regular file, write to a FIFO file, send a signal, write some text into a shared memory segment... There are hundreds of ways to do this.
May you provide an example, please? It would be good to send a signal from cmd2 to cmd1, but how may I tell cmd1 to interpret the signal I a proper way (changing sqlprompt)?

---------- Post updated at 01:57 PM ---------- Previous update was at 01:46 PM ----------

I found something. When I have sqlplus running and in another session I do:
Code:
# echo "TEst;" > /proc/<PIDofSQLPLUS>/fd/0

then in sqlplus I receive:
Quote:
myuser@mydb SQL> TEst;
But the message is not interpreted at all (is only printed) by sqlplus, unfortunately.

---------- Post updated at 04:26 PM ---------- Previous update was at 01:57 PM ----------

According to my last update I found this (linux - sending command to process using /proc - Stack Overflow):
Quote:
You can't do that. /proc/fd/0 is (usually) not a pipe which you can write to and give the process input.
What you need to do, is invoke the process with its stdin coming from something that IS a pipe (or socket etc) so that you can write stuff into it.
A named pipe MAY work here (see mknod(1) or mkfifo(3) ).
# 11  
Old 02-07-2018
Examples you provided cannot be used for inter process communication.
Only way i can think now are shell coprocesses, with using shell only as a programming tool.

As other mentioned, other languages/tools offer easier way to achieve your goal using various techniques which are not that 'transparent' to use in shell language or are great overhead to code.

You should think about switching to database side completely (stored procedures, pl/sql) to get the desired processing with minimal code investment and (probably) best performance.
But this is just a wild guess, since the whole processes is not known to me.

Rewrite and remodel is sometimes best way to fix your program when features required just cannot keep up.

Hope that helps
Regards
Peasant.
# 12  
Old 02-07-2018
If you use the Korn shell you could use the so-called "Coprocess facility". Notice, though, that only the Korn shell supports these, the solution will not be portable to any other Bourne-shell-descendant (and most probably not even to the many ksh-clones which are only "mostly compatible"). Basically you are starting an asynchronously running background job which communicates with the main job via (bidirectional) pipes.

You start the coprocess with

Code:
command |&

and then process the incoming/outgoing messages with read -p and print -p. Per default IOD 4 and 5 are used for this but can be redirected via exec if you have several coprocesses at the same time.

I hope this helps.

bakunin
# 13  
Old 02-07-2018
Quote:
Originally Posted by JackK
I didn't know about coprocesses before. In my case, I think, writing a parser with coprocesses is not needed and too complicated (for such a small requirement).
Once again, what you're asking for isn't exactly trivial.

You can communicate with the previous process with a named pipe, but this will be a bit complicated to set up and prone to deadlocks afterwards (who's waiting for whom?) With all those caveats, here is how you do it:

Code:
#!/bin/bash

exec 1>&3 # Save stdout into FD 3 if we need it
mkfifo /tmp/$$

echo "fifo is /tmp/$$"

(       # Process A.  stdout writes to pipe.
        exec < /tmp/$$ # Redirect stdin from named pipe

        for X in 1 2 3
        do
                read ASDF
                echo "string: $ASDF"
        done
) | (
        # Process B.  stdin reads from pipe.
        exec > /tmp/$$  # Redirect stdout into named pipe
        rm -f /tmp/$$

        for X in 1 2 3
        do
                echo $X
                read REPLY
                echo "Reply was '$REPLY'" >&3 # Write to old stdout
        done
)

The sticky part is opening the named pipe. That has to be done in different subshells because exec < namedpipe and exec > namedpipe must happen simultaneously: If two processes aren't trying to open it, the will force your program to wait. This for example will not work:

Code:
exec 5<namedpipe # Will wait forever since the line below it will not run
exec 6>namedpipe

$$ is just a convenient random-ish number.

Last edited by Corona688; 02-07-2018 at 12:04 PM..
# 14  
Old 02-07-2018
Quote:
Originally Posted by JackK
... ... ...
Quote:
Originally Posted by Don Cragun
Send email to yourself, send a message to a message queue, write to a regular file, write to a FIFO file, send a signal, write some text into a shared memory segment... There are hundreds of ways to do this.
May you provide an example, please? It would be good to send a signal from cmd2 to cmd1, but how may I tell cmd1 to interpret the signal I a proper way (changing sqlprompt)?

... ... ...
Here is one example of using the presence of a file to act as a semaphore to allow a second process in a pipeline to notify the first process in that same pipeline that it has seen something written by that first process (and it does this twice). If more information needs to be transferred between these two processes, the 2nd process could write any amount of data it wants into the file instead of just creating the file. For this example, we have two shell scripts named cmd1 and cmd2.
The code to be placed in cmd1:
Code:
#!/bin/bash
FILE=file
FOUND=0

for ((LOOP=1; LOOP < 20; LOOP++))
do	if [ -f "$FILE" ]
	then	echo "$FILE found.  Incrementing FOUND."
		rm "$FILE"
		FOUND=$((FOUND + 1))
	fi
	echo "LOOP is $LOOP"
	echo "FOUND is $FOUND"
	sleep 5
done | tee /dev/tty

Note that the tee in this script allows you to see everything that is being written into the pipeline.

The code to be placed in cmd2:
Code:
#!/bin/bash
FILE=file
sleep 1
echo "Starting $0; looking for 'LOOP is 5'"

while read -r line
do	if [ "$line" = 'LOOP is 5' ]
	then	echo "'LOOP is 5' found; creating $FILE; looking for 'LOOP is 15'"
		> "$FILE"
	fi
	if [ "$line" = 'LOOP is 15' ]
	then	echo "'LOOP is 15' found; creating $FILE again"
		> "$FILE"
	fi
done
echo "$0 hit EOF; exiting"

When you run these two scripts in a pipeline using:
Code:
./cmd1 | ./cmd2

you will see output on your screen similar to:
Code:
LOOP is 1
FOUND is 0
Starting ./cmd2; looking for 'LOOP is 5'
LOOP is 2
FOUND is 0
LOOP is 3
FOUND is 0
LOOP is 4
FOUND is 0
LOOP is 5
FOUND is 0
'LOOP is 5' found; creating file; looking for 'LOOP is 15'
file found.  Incrementing FOUND.
LOOP is 6
FOUND is 1
LOOP is 7
FOUND is 1
LOOP is 8
FOUND is 1
LOOP is 9
FOUND is 1
LOOP is 10
FOUND is 1
LOOP is 11
FOUND is 1
LOOP is 12
FOUND is 1
LOOP is 13
FOUND is 1
LOOP is 14
FOUND is 1
LOOP is 15
FOUND is 1
'LOOP is 15' found; creating file again
file found.  Incrementing FOUND.
LOOP is 16
FOUND is 2
LOOP is 17
FOUND is 2
LOOP is 18
FOUND is 2
LOOP is 19
FOUND is 2
./cmd2 hit EOF; exiting

In your cmd1 script, you can run whatever commands you want to run when the semaphore file is found to alter the sqlplus prompt.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Solaris

RWSocket::send: Broken pipe Error in /var/adm/messages

Hi Guys, I am getting some strange error in /var/adm/messages in my Solaris 10 box with Veritas Cluster and EMC storage. bash-3.00$ cat /var/adm/messages | egrep -v "lw8|snmp|sshd|xntpd|kern.info|LOGIN|link|service|started|finished|repeated|SS7 Log-daemon|success" Dec 18 09:58:35 GAMMa2... (1 Reply)
Discussion started by: vivek.goel.piet
1 Replies

2. Shell Programming and Scripting

Perl to send previous and current value

For example, I have a file called number.txt. x y 1 1 2 4 3 9 4 6 5 5 6 6 7 9 8 4 9 1 10 0 ... And I want to print out the value of x and y, if y%4==0 and the next value of y%4==0. Thus, the sample output is: 1 1 *because the previous x before 2 is 1 2 4 *because 4%4 == 0 7 9... (2 Replies)
Discussion started by: Tzeronone
2 Replies

3. Linux

Perl program to print previous set of lines once a pattern is matched

Hi all, I have a text data file. My aim here is to find line called *FIELD* AV for every record and print lines after that till *FIELD* RF. But here I want first 3 to four lines for very record as well. FIELD AV is some where in between for very record. SO I am not sure how to retrieve lines in... (2 Replies)
Discussion started by: kaav06
2 Replies

4. UNIX for Advanced & Expert Users

sftp error:- Couldn't send packet: Broken pipe

Hi, I am trying to sftp a large file(appx. 2 GB size) from solaris 10 to a Linux server. While sftping(with no options), connection is terminated after some time with broken pipe error. sftp with option -R1 or -B1500 is successful. Linux server ssh Version: OpenSSH_3.9p1, OpenSSL 0.9.7a... (3 Replies)
Discussion started by: brij123
3 Replies

5. Homework & Coursework Questions

pipe program in C

Hello guys, my professor give me 2 days to study and make a program usign pipe, fork in c i need to do a program read a arq.txt the father process read the file and the child print ! 2. Relevant commands, code, scripts, algorithms: like this Code: #include <stdio.h>... (1 Reply)
Discussion started by: beandj
1 Replies

6. Programming

pipe program in C

Hello guys, my professor give me 2 days to study and make a program usign pipe, fork in c i need to do a program read a arq.txt the father process read the file and the child print ! like this #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> int main (){ ... (1 Reply)
Discussion started by: beandj
1 Replies

7. Solaris

sendmail pipe to a program.

Hello, I recently upgraded our server from Solaris 8 to 9. The sendmail is unabled to pipe the email to a perl script. I can send and received email to local and external mail, but the script did not get the email. There is no error in the log and I could not find any thing on the web. Here... (0 Replies)
Discussion started by: ld98
0 Replies

8. Shell Programming and Scripting

Writing a program to receive the GPS data and send to other server

Hi, I would like to write a program to receive the GPS data and then send the data via network to other program. All of the program is not write yet(include host and sender) All of the server OS is unix or linux Could you mind to give me some idea to do this? Thanks so much! Ken ... (2 Replies)
Discussion started by: kenlok
2 Replies

9. UNIX for Dummies Questions & Answers

Script to open program and send/execute command in program

Hi, i want to write a script that executes a program (exec?) . this program then requires a filename as input. how do i give it this input in the script so the program will be complete run and close by the script. e.g. exec prog.exe program then asks for filename "enter filename:"... (1 Reply)
Discussion started by: tuathan
1 Replies

10. Programming

C++ How to use pipe() & fork() with stdin and stdout to another program

Hi, Program A: uses pipe() I am able to read the stdout of PROGAM B (stdout got through system() command) into PROGRAM A using: * child -> dup2(fd, STDOUT_FILENO); -> execl("/path/PROGRAM B", "PROGRAM B", NULL); * parent -> char line; -> read(fd, line, 100); Question:... (2 Replies)
Discussion started by: vvaidyan
2 Replies
Login or Register to Ask a Question