Bug 243322 - Behavior change on "cat filename | while read varname" construct
Behavior change on "cat filename | while read varname" construct
Status: CLOSED NOTABUG
Product: Red Hat Enterprise Linux 4
Classification: Red Hat
Component: bash (Show other bugs)
4.5
All Linux
low Severity medium
: ---
: ---
Assigned To: Roman Rakus
Ben Levenson
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2007-06-08 11:43 EDT by paul boin
Modified: 2014-01-12 19:06 EST (History)
3 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2010-04-06 06:52:27 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description paul boin 2007-06-08 11:43:26 EDT
Description of problem:

We have a script that monitors our shop for static passwords.  It's called from
cron every week.  Worked fine for a long time.  May 27 was good.  June 3 report
only had the first entry printed and then it bailed.

Even now, the script was running fine from console, but broken from cron.

Followed the traditional steps of verifying SHELL and PATH, and spent a long
time printing logs, running with the '-x' option, etc.

Final analysis:

Before the 5/30 upgrade to bash-2.05b-41.7, this job ran fine from cron.  Since
then, no worky.


As a workaround, I can change this:

cat "filename" | while read host
do
 . 
 . 
done

To this:
for host in `cat filename`
do
 . 
 . 
done


Now I'm just wondering what else might be having problems.  We use the "cat |
while read" construct all over the place...
Comment 1 paul boin 2007-06-08 11:44:09 EDT
#!/bin/sh

export SHELL="/bin/sh"
export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin"
# echo "report $SHELL" >> /tmp/shelllog
# echo "report $PATH" >> /tmp/shelllog


#
# RedHat
#
for OS in rhel3 rhel3-64 rhel4 rhel4-64 rhel5 rhel5-64
do
    if [ ! -d /usr/local/etc/rdist-$OS/Stats/Hosts ]
    then
        echo
        echo "ERROR: /usr/local/etc/rdist-$OS/Stats/Hosts is missing."
        echo
        continue
    fi
    cd /usr/local/etc/rdist-$OS/Stats/Hosts
    ls -t | egrep -v '^1hosts' > /tmp/files.$$
    ls -1 | awk -F'_' '{print $1}' | egrep -v '^1hosts' | sort -u > /tmp/hosts.$$

    # cat "/tmp/hosts.$$" | while read host
    for host in `cat /tmp/hosts.$$`
    do
        file=`grep $host[_] /tmp/files.$$ | head -1`
        grep -a "Password set" $file > /tmp/pwset.$$
        grep -qv root /tmp/pwset.$$
        if [ $? -eq 0 ]
        then
            egrep -q "Mobile PCI Bridge|Mobile CPU|Mobile Pentium|Mobile
Intel|Intel Corporation Mobile" $file
            if [ $? -eq 0 ]
            then
            laptop="*** LAPTOP ***"
            else
            laptop=""
            fi
            ip=`host $host | awk '{print $4}' | head -1`
            echo "$host ($ip)    $laptop"
            echo "================================================="
            grep -v root /tmp/pwset.$$
            echo
        fi
    done
    rm /tmp/files.$$ /tmp/hosts.$$ /tmp/pwset.$$
done


Comment 2 paul boin 2007-06-08 12:04:21 EDT
Well, maybe I'm wasting time, sorry...

I did a "rpm -ivh --force --oldpackage bash-2.05b-41.5.i386.rpm", and then re-ran.

The "cat | while read" is still broken, and the "for variable in" method still
works.

Odd...  What are the chances that bash changed in between good and bad runs, but
it's not the problem?

Comment 3 Roman Rakus 2008-03-25 09:38:01 EDT
cat | while read works for me in version bash-2.05b-41.7, also works in
bash-3.0-19.6.

I have simple script:
#!/bin/bash
cat file.txt | while read text
do
        echo $text
done

and works perfectly. Can you please describe where is the problem? What exactly
means "not working"? It is possible that the problem is in file /tmp/hosts.$$.
But I'm just guessing.
Can you please write more information about your problem?
Thank you.
Comment 4 Roman Rakus 2010-04-06 06:52:27 EDT
Please read bash FAQ. Section E4;
--snip--
Each element of a pipeline, even a builtin or shell function,
runs in a separate process, a child of the shell running the
pipeline.  A subprocess cannot affect its parent's environment. 
When the `read' command sets the variable to the input, that
variable is set only in the subshell, not the parent shell.  When
the subshell exits, the value of the variable is lost. 
--snip--

Closing this one as notabug...

Note You need to log in before you can comment on or make changes to this bug.