2

Shell script on which I am working is having one SQL query which fetches multiple column and multiple rows from DB:

get_names() {
    $ORACLE_HOME/bin/sqlplus -s usr/pwd <<EOF
        SELECT id,name,age FROM table;
        Exit;
EOF
}

Then, to read this result we are piping the function's output:

get_names | while read sid p_name p_age ; do ... done.

Now, because of |, a subshell is getting created, which I need to avoid. Is there any alternative present for this issue?

We want to break that pipe statement to avoid child process of it.

  • A process must exist on each side of a pipe. On one side it is sqlplus on another it must something else. You could write a program to do the work of that while but that would still be a process. – grochmal Jul 21 '16 at 13:30
  • 1
    Why must you avoid a child process? (this may help to get you the best answer). – ctrl-alt-delor Jul 21 '16 at 14:30
3

You can use process substitution if you're on a shell that supports it (e.g., bash, ksh, or zsh):

while read sid p_name p_age ; do ...; done <  <(get_names)

This is required in bash if you want the final link of your pipeline to be your running shell (so that it may have an effect on your running shell):

for sh in bash ksh zsh; do 
     echo $sh:; $sh -c 'while read var; do i=$var
     done < <(printf "%s\n" 1 2); echo $i '
done

Output:

bash:
2
ksh:
2
zsh:
2

Whereas with a regular pipeline:

for sh in bash ksh zsh; do 
     echo $sh:; $sh -c 'printf "%s\n" 1 2 | 
         while read var; do i=$var; done ; echo $i '; 
done

the assignment doesn't stick because bash runs the while loop in a subshell rather than the current shell:

bash:

ksh:
2
zsh:
2
  • Note that among the shells that support <(...), this trick is only needed for bash. In the others in ... | while..., the while loop is not run in a subshell. – Stéphane Chazelas Jul 21 '16 at 14:57
  • @StéphaneChazelas Interesting. I didn't know that. I've expanded my answer with a proof of that, if you don't mind. Thank you for pointing that out! – PSkocik Jul 21 '16 at 15:13
-1

You could do it all in a single python process (other languages are available).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.