Skip to Main Content
  • Questions
  • Problem running a shell script that contains pipes

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Gwen.

Asked: February 10, 2017 - 7:04 pm UTC

Last updated: February 11, 2017 - 2:48 am UTC

Version: 12.1.01

Viewed 1000+ times

You Asked

Hello,

I am using a bash script to generate passwords. This is a bash shell script.

When we run this in bash (on Linux) outside of SQL*Plus, it executes fine. We are running Oracle Enterprise Edition 12c on a two-node RAC.

When I log into SQL*Plus using a local account (sqlplus / as sysdba OR sqlplus gwen_dallas), and use the host command or exclamation mark to run it, it runs fine (note I've changed the script name and used dummy output to protect the innocent):

SQL>!foobar.sh
A1b2C3d4...

However, when I log into SQL*Plus specifying a SID or Service (sqlplus gwen_dallas@foobar), I find that our script hangs. This is particularly a problem in 12c as this seems to be necessary for connecting to a pluggable database.

Based on my debugging, it seems to be hanging on a "head" command that is part of pipe (note, I am only quoting part of this line so as not to give away too many secrets about how we use passwords; but suffice it to say that after the head the result is the same, but if I get rid of the head we have infinite output from fold):

pw=$(tr -cd '[:alnum:]' < /dev/urandom | fold -w32 | head -n1 ...)

It seems to me that a possible explanation here is that SIGPIPE is not being passed from head back to fold and tr, thus causing the script to hang indefinitely.

In 12c, I have even seen different output when running "trap -p SIGPIPE" (trap -- '' SIGPIPE vs. <null>; the problem only occurs in the first case but not the second). Also, if I open a subshell from within sqlplus and manually set the trap for SIGPIPE (trap " " SIGPIPE), the problem seems to go away, at least within that subshell. (However this workaround does not work for me on 11g).

SQL>!bash
[oracle@foo]foobar.sh
<hangs forever until I hit Ctrl+C>
[oracle@foo]trap " " SIGPIPE
[oracle@foo]foobar.sh
E5f6G7h8...
<terminates happily>
[oracle@foo]exit
SQL>...

Has anyone else seen this problem before, with the behavior of pipes in bash subshells from within SQL*Plus? Is this intended behavior or is this a possible defect?

(Note: I have proposed running a head on /dev/urandom as the first statement in the pipe, and I think that works, but that would not be my first choice as it would change the business logic of a script we've been using for years).

Thanks!

and Connor said...

I've reproduced the same on my own instance here, so it appears to be a bug. Similarly for korn shell as well, aka, x=`command | command`. And I also reproduced it with 'sqlcl'

My guess is we're "playing about" with stdout to bring the output back to SQL Plus, and thats interfering with the conventional operation of the script.

A workaround that was successful for me was an additional layer.

script1.sh:

!/bin/bash
script2.sh

where script2.sh contains the "problematic" code.

If thats not a suitable workaround for you, log a bug with Support.

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

A reader, February 11, 2017 - 3:27 am UTC


More to Explore

Multitenant

Need more information on Multitenant? Check out the Multitenant docs for the Oracle Database