LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-05-2011, 12:48 PM   #1
mark1967
LQ Newbie
 
Registered: Sep 2011
Posts: 3

Rep: Reputation: Disabled
piping email to a bash script for processing


Hi all
I want to turn the following command into a bash script:

cat file | ssh user@system 'script'
ssh is setup so that I can do this without a password for this specific command.

However I'm not getting far.
The only way I can find to get a bash script to read a file is using 'read', which is one line at a time, and this doesn't work here.

Is there any way I can get all of the input file and pipe it into an ssh command?
I feel like I'm missing something fairly basic but I've been at this for a few hours now and I'm not getting too far.

Thanks
 
Old 09-05-2011, 01:44 PM   #2
Tinkster
Moderator
 
Registered: Apr 2002
Location: earth
Distribution: slackware by choice, others too :} ... android.
Posts: 23,067
Blog Entries: 11

Rep: Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928
You could try making the 'script' a forced command; I used that in
a previous employment for a certain application - not w/ emails,
but with lengthy textual output; and not into bash, but into perl.
Shouldn't make a difference for the use-case, though.



Cheers,
Tink
 
Old 09-05-2011, 02:07 PM   #3
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by mark1967 View Post
However I'm not getting far.
The only way I can find to get a bash script to read a file is using 'read', which is one line at a time, and this doesn't work here.
Can you post a short version of the script? In what way does the script "read" the file data? Are you wanting to pass the data as a filename to something else, e.g.
Code:
#!/bin/bash

./myprogram-needs-a-file <(cat)
I seem to recall a circumstance where read wouldn't work directly so I had to cat | read.
Kevin Barry
 
Old 09-05-2011, 02:43 PM   #4
KenJackson
Member
 
Registered: Jul 2006
Location: Maryland, USA
Distribution: Fedora and others
Posts: 757

Rep: Reputation: 145Reputation: 145
You could cat the data to a local temporary file and then work on the temp.
I just ran this little experiment:

File abc on the local host:
Code:
abcd
xx example yy
efgh
File ~/bin/testabc on the remote host (~/bin is in PATH):
Code:
#!/bin/sh
FILE=/tmp/mail$$
cat > $FILE
trap "/bin/rm -f $FILE" 0 1 2 3 13 15

# Now process $FILE, e.g.:

grep example $FILE
Command on the local host:
Code:
cat abc | ssh remote testabc
xx example yy
 
Old 09-06-2011, 10:09 AM   #5
mark1967
LQ Newbie
 
Registered: Sep 2011
Posts: 3

Original Poster
Rep: Reputation: Disabled
Follow-up to my question

Tinkster - thanks for the input - I think Perl is the answer, it's fairly easy just using Net::SSH but I thought that bash should be easy too.


KenJackson - that's a neat idea thanks. the problem is that postfix executes milters (mail filters) directly piping the mail to the script, and it's going to be much more robust if I don't have to break it up in this way. I think it would be better to revert to perl.


ta0kira - hopefully the above answers your question. Postfix pipes the mail into the script directly. If the script was local, that would be fine, but the script is remote, so efectively postfix will
cat mail_file | localscript.
Inside "localscript" I want something that reads mail_file and pipes that to "ssh user@remote_system milter_script"
I hope that makes sense.

I have to say I don't really have any example to post yet. i found read fairly quickly but then couldn't see how to read all of the mail into something that I could pipe to ssh.
 
Old 09-06-2011, 10:33 AM   #6
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by mark1967 View Post
ta0kira - hopefully the above answers your question. Postfix pipes the mail into the script directly. If the script was local, that would be fine, but the script is remote, so efectively postfix will
cat mail_file | localscript.
Inside "localscript" I want something that reads mail_file and pipes that to "ssh user@remote_system milter_script"
I hope that makes sense.
So having a stand-alone line ssh user@remote_system milter_script doesn't work? You shouldn't need to pipe to ssh if the data is already being piped to the script. Are you trying to protect standard input from being read by something besides ssh?
Code:
#!/bin/bash

exec 3<&0 < /dev/null

read stuff #<-- nothing is read here

ssh user@remote_system milter_script <&3 #<-- only ssh can read standard input
Kevin Barry
 
Old 09-06-2011, 12:09 PM   #7
Tinkster
Moderator
 
Registered: Apr 2002
Location: earth
Distribution: slackware by choice, others too :} ... android.
Posts: 23,067
Blog Entries: 11

Rep: Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928
Quote:
Originally Posted by mark1967 View Post
Tinkster - thanks for the input - I think Perl is the answer, it's fairly easy just using Net::SSH but I thought that bash should be easy too.
I didn't think of perl as "the answer" up there, but of the forced
command. Have a read about them: they work fairly well. Of course
I have to admit I never tried bash on the receiving end.


Cheers,
Tink
 
Old 09-06-2011, 05:52 PM   #8
KenJackson
Member
 
Registered: Jul 2006
Location: Maryland, USA
Distribution: Fedora and others
Posts: 757

Rep: Reputation: 145Reputation: 145
Quote:
Originally Posted by mark1967 View Post
KenJackson - that's a neat idea thanks. the problem is that postfix executes milters (mail filters) directly piping the mail to the script, and it's going to be much more robust if I don't have to break it up in this way. I think it would be better to revert to perl.
Do what you must.
But I changed my experiment script on the remote server to this:
Code:
#!/bin/sh
DATA="$(< /dev/stdin)"

# Now process the text, e.g.:

echo "$DATA" | grep example
And it works the same way at the local host:
Code:
cat abc | ssh remote testabc
xx example yy
 
Old 09-06-2011, 06:42 PM   #9
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by KenJackson View Post
But I changed my experiment script on the remote server to this:
Code:
#!/bin/sh
DATA="$(< /dev/stdin)"

# Now process the text, e.g.:

echo "$DATA" | grep example
This has a slight functional difference in that any null characters will be discarded. I don't know enough about the problem to know if that's an issue (i.e. if binary data will ever be sent), however.
Kevin Barry
 
Old 09-06-2011, 07:06 PM   #10
Tinkster
Moderator
 
Registered: Apr 2002
Location: earth
Distribution: slackware by choice, others too :} ... android.
Posts: 23,067
Blog Entries: 11

Rep: Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928
Quote:
Originally Posted by Tinkster View Post
I didn't think of perl as "the answer" up there, but of the forced
command. Have a read about them: they work fairly well. Of course
I have to admit I never tried bash on the receiving end.


Cheers,
Tink

And with these words:
Code:
on machine 2
user@machine2$ echo command="/home/p652900/test",no-port-forwarding,no-X11-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAoGgEV84faPDa9hsUmGUi2ZixGqAe03jQQ0Fkaz1llgZ9RCex/EJZ/Lny771t+oXyuYxaOtOIlya8oZDfBvaaYhWqxUPq81eF9PL43+ytI/C6m9nNhv4f4Tw12usd/Xi7qPUmaAT9fuWQCYHQniOoCLgY6fDcPTb97EDEIl9rIk4C8U+mij/ywq+UhgFLCmOtQM0RBw+q2bPoyjRm53RifAys1snjWlvGKxATGntI2TFE+sk933Id9MtOz/bB2yULWnRa9MPFXmYvVsJ1Hx0e/Ds4iSUy8k+K0HnQOvneAEGZG98bOzCmOnCvchOk8wqtwzSfPOkrMQ3QzvaqcmKOLQ== user@machine1 >> ~/.ssh/authorized_keys

vim /home/user/test
#!/bin/bash
count=1
while read line
do
echo $count $line 
count=$(($count + 1))
done


on machine 1
cat /etc/shells | ssh -t user@machine2
1 /bin/bash
2 /bin/ash


Cheers,
Tink

Last edited by Tinkster; 09-06-2011 at 07:10 PM.
 
Old 09-07-2011, 02:14 AM   #11
mark1967
LQ Newbie
 
Registered: Sep 2011
Posts: 3

Original Poster
Rep: Reputation: Disabled
Wow - that's all exactly what I need - thanks all
 
Old 09-07-2011, 02:02 PM   #12
Tinkster
Moderator
 
Registered: Apr 2002
Location: earth
Distribution: slackware by choice, others too :} ... android.
Posts: 23,067
Blog Entries: 11

Rep: Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928Reputation: 928
Out of curiosity: which route did you take in the end?
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Forward email to script for processing? aaronvegh Programming 10 01-14-2011 11:34 AM
Write a script to send an email from bash kpelczar Linux - Software 5 02-09-2005 04:19 PM
bash script to email updated ip ericnmu Linux - Networking 1 10-01-2004 10:30 PM
Piping to ttoogg in bash script goofyheadedpunk Linux - General 8 06-06-2004 05:44 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:52 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration