HPE Community read-only access December 15, 2018
This is a maintenance upgrade. You will be able to read articles and posts, but not post or reply.
Hours:
Dec 15, 4:00 am to 10:00 am UTC
Dec 14, 10:00 pm CST to Dec 15, 4:00 am CST
Dec 14, 8:00 pm PST to Dec 15, 2:00 am PST
System Administration
cancel
Showing results for 
Search instead for 
Did you mean: 

output | read B; echo $B ( now it works now it doesn't )

 
SOLVED
Go to solution
Gilbert Standen_1
Frequent Advisor

output | read B; echo $B ( now it works now it doesn't )

Hi, I often use scripts of the following type, for example:
------
#!/bin/ksh
# Program Notes
echo "set linesize 200 heading off echo off verify off feedback off pagesize 0
select max(sequence#) from v\$log_history;
quit
" | sqlplus -s / as sysdba | sed 's/^[ \t]*//;s/[ \t]*$//' | sed '/^$/d' | read maxseq
echo $maxseq
------
My question is that i find that on some boxes the "read" command will read in the output from pipe into the variable "maxseq" but then when I put this on other boxes, it does not, in other words, sometimes "read" as used above does not work. I don't really understand what is affecting whether or not this will work.

Is there a more reliable alternative for reading the output of the sqlplus call into a variable that is reliably portable across different boxes?

Thanks, Gil
If I could take one thing with me into the next world it would be my valid login to HP ITRC Forums
19 REPLIES
James R. Ferguson
Acclaimed Contributor

Re: output | read B; echo $B ( now it works now it doesn't )

Hi Gil:

WHere this works, you are probably running an HP-UX POSIX shell or a Korn (ksh) one. Where this fails, you are probably running the Bash shell.

With the HP-UX Posix or ksh shell, this works:

# echo a b c | read X Y Z
# echo ${X}
a

Under Bash, nothing is printed :-)

Regards!

...JRF...
James R. Ferguson
Acclaimed Contributor

Re: output | read B; echo $B ( now it works now it doesn't )

Hi (gain) Gil:

...and I forgot to add, if it is in Bash environments that you have the problem, then this:

# echo a b c | read X Y Z

...can be rectified with this:

# echo a b c|while read X Y Z;do echo ${X};done
a

Regards!

...JRF...
Gilbert Standen_1
Frequent Advisor

Re: output | read B; echo $B ( now it works now it doesn't )

Thanks for the reply. But still have the same problem although I tried to implement your changes:

echo "set linesize 200 heading off echo off verify off feedback off pagesize 0
select max(sequence#) from v\$log_history;
quit
" | sqlplus -s / as sysdba | sed 's/^[ \t]*//;s/[ \t]*$//' | sed '/^$/d' | while read maxseq; do echo ${maxseq}; done
echo $maxseq
echo ${maxseq}

last two lines output null. The main command does output the current value of the query = "13134" but it is not getting "stored" into "maxseq" and I can't subsequently reference it. Am I doing something incorrectly in the way I implemented your suggested code?
If I could take one thing with me into the next world it would be my valid login to HP ITRC Forums
Tingli
Esteemed Contributor

Re: output | read B; echo $B ( now it works now it doesn't )

Have you got anything before the "sed"?
Gilbert Standen_1
Frequent Advisor

Re: output | read B; echo $B ( now it works now it doesn't )

yes, this:

echo "set linesize 200 heading off echo off verify off feedback off pagesize 0
select max(sequence#) from v\$log_history;
quit
" | sqlplus -s / as sysdba | sed......
If I could take one thing with me into the next world it would be my valid login to HP ITRC Forums
Tingli
Esteemed Contributor

Re: output | read B; echo $B ( now it works now it doesn't )

I mean, just type in:

echo "set linesize 200 heading off echo off verify off feedback off pagesize 0
select max(sequence#) from v\$log_history;
quit
" | sqlplus -s / as sysdba
Gilbert Standen_1
Frequent Advisor

Re: output | read B; echo $B ( now it works now it doesn't )

sorry cannot figure out what point you are making tingli. I need to take the output of that command and read it into a variable. That's the goal. Usually I can do that by just "| read" but as pointed out not all shells support this so I am looking for alternative code to accomplish same. I need to use the value stored to the variable later on in additional scripting.
If I could take one thing with me into the next world it would be my valid login to HP ITRC Forums
Tingli
Esteemed Contributor

Re: output | read B; echo $B ( now it works now it doesn't )

Just want to know whether sqlplus works.
Gilbert Standen_1
Frequent Advisor

Re: output | read B; echo $B ( now it works now it doesn't )

i see - yes it works. everything including the 2 sed expressions works - it outputs the current sequence# in v$log_history. thanks tingli. good thought.
If I could take one thing with me into the next world it would be my valid login to HP ITRC Forums
Tingli
Esteemed Contributor

Re: output | read B; echo $B ( now it works now it doesn't )

Maybe your line is too long while the stty columns set to 80 only.
James R. Ferguson
Acclaimed Contributor

Re: output | read B; echo $B ( now it works now it doesn't )

Hi Gil:

> last two lines output null.

Then I would suspect that your 'sed' may have eliminated everything but whitespace.

Notice that:

# sed -e '/^$/d'

...doesn't delete lines consisting of spaces. You probably want:

# sed -e '/^[ \t]*$/d'

...where the '\t' is a TAB character and there is a blank (space) before that.

Too, it is cheaper to do:

# sed -e 'sed '...' -e sed -e '...'

...than to run a pipe of sed-to-sed.

Regards!

...JRF...
Gilbert Standen_1
Frequent Advisor

Re: output | read B; echo $B ( now it works now it doesn't )

Jim thanks for responding and for the suggestions. It's appreciated.

However, nope that is not it. I tried your alternate sed expression and still same problem with the new sed code for blank lines. I put a wc -c on the end of the expression and got "6". I put a wc -l on the end of the expression and got "1". The expression outputs the correct numeric 5-digit value on each run, on one line only.

I talked to another sysadmin and he said this is due to fact that this is linux running on the HP box and that the so-called "ksh" on linux is not a "true" ksh shell and so this is not working the same as it would on HP-UX.

How to do? So I still cannot take the output of the pipes and save it to a variable. Any suggestions of alternate method to get the output of the expression stored into a variable that can be used later in the script?

Regards!

gil
If I could take one thing with me into the next world it would be my valid login to HP ITRC Forums
James R. Ferguson
Acclaimed Contributor

Re: output | read B; echo $B ( now it works now it doesn't )

Hi Gil:

I should add that some variations of 'sed' do _not_ understand '\t'. THus, instead of writing:

# sed -e '/^[ \t]*$/d'

...to delete blank lines, do:

# sed -e '/^[ ]*$/d'

...where the bracketed characters are a space and a TAB character as typed on your keyboard. Since I despise trying to read this later, I use Perl:

# ... | perl -pe 's/^\s*$//'

...which says substitute any _whitespace_ present (spaces, tabs, newlines) with nothing if the whitespace occupies the whole line.

Regards!

...JRF...
Solution

Re: output | read B; echo $B ( now it works now it doesn't )

I still think you must be using bash on the Linux box, not ksh, as this sounds like exactly the issue on bash with pipelines being run in subshells... when I've tried to kae code more portable, I've found functions can help... try this:

function GetMaxSeq
{
echo "set linesize 200 heading off echo off verify off feedback off pagesize 0
select max(sequence#) from v\$log_history;
quit
" | sqlplus -s "/ as sysdba" | sed 's/^[ \t]*//;s/[ \t]*$//' | sed '/^$/d'
}

maxseq=$(GetMaxSeq)

echo ${maxseq}



HTH

Duncan

HTH

Duncan
Gilbert Standen_1
Frequent Advisor

Re: output | read B; echo $B ( now it works now it doesn't )

Hi Jim,
Look it's not the sed or perl issue. If I run this:

echo "A" | read B
echo $B

the "echo $B" is unset null blank.

it's an issue with piping to "read" on linux - not a sed / perl issue. I guess "read" cannot be used in this way on the flavor of ksh that linux supports.

so what I am needing is some sort of alternate way to send output of a command, or a bunch of piped commands, etc. to a variable.

Is there some way other than "read" to do that?

Thanks for your help, Gil
If I could take one thing with me into the next world it would be my valid login to HP ITRC Forums
Gilbert Standen_1
Frequent Advisor

Re: output | read B; echo $B ( now it works now it doesn't )

Duncan - works great! Problem solved! Jim thanks for all the good pointers on sed & perl. Man this forum is gold. My personal quote for my forum profile: "If I could take one thing with me into the next world it would be my valid login to HP ITRC Forums." As true today as it was in 2004. God I love this place! I'm just a lowly Oracle DBA and frankly I'm lost...
If I could take one thing with me into the next world it would be my valid login to HP ITRC Forums
James R. Ferguson
Acclaimed Contributor

Re: output | read B; echo $B ( now it works now it doesn't )

Hi Gil:

This is what I said originally and what Duncan has reinfourced:

# echo "A" | while read B; do echo ${B};done
A

Regards!

...JRF...
Gilbert Standen_1
Frequent Advisor

Re: output | read B; echo $B ( now it works now it doesn't )

On my server:

> echo "A" |while read B; do echo ${B};done
A
> echo $B
>

Duncan's:

> function gimme
> {
> echo "A"
> }
> maxseq=$(gimme)
> echo ${maxseq}
A

Not same. :-)
If I could take one thing with me into the next world it would be my valid login to HP ITRC Forums
Gilbert Standen_1
Frequent Advisor

Re: output | read B; echo $B ( now it works now it doesn't )

Actually, I should have written:

On my server:

> echo "A" |while read B; do echo ${B};done
A
> echo $B
>

Duncan's:

> function gimme
> {
> echo "A"
> }
> B=$(gimme)
> echo ${B}
A

Not same. :-) What I need and have now is a way to get the piped output stored in a variable. Thanks All. Mission accomplished.
If I could take one thing with me into the next world it would be my valid login to HP ITRC Forums