LZozzy
LZozzy

Reputation: 21

WHILE loop not looping

I'm fairly new to Linux and shell scripting.

My problem is, that the script should read 2 tokens from a file called "list" - using these tokens, it creates a user and depending on the second token, a sub folder. It does this just fine - but only once. Only ONCE. Is there a problem with my WHILE loop?

Here is a few sample lines from "list":

egyes n
kettes y
harmas y

Here's the script:

#!/bin/bash
echo " " >> /root/userpass.txt
most=$(date)

while read user rr; do
    p1=${user:0:2}
    p2=${user:3:4}
    pass=$p1$RANDOM$p2
    echo $user - $pass --" LÉTREHOZVA: "$most >> /root/userpass.txt

    adduser $user > /dev/null
    echo $user:$pass | chpasswd > /dev/null

    uhome=/home/$user

    if [ $rr=="y" ]; then
            mkdir $uhome/rockandroll
            chown $user $uhome/rockandroll
    fi

    mkdir $uhome/res-devres
    chown $user $uhome/res-devres

    ftpc=/etc/proftpd/proftpd.conf

    echo "#"$1 >> $ftpc
    echo "<Directory "$uhome"/res-devres/>" >> $ftpc
    echo '  <Limit CDUP XCUP STOR LIST CWD XCWD STOU>' >> $ftpc
    echo '          AllowAll' >> $ftpc
    echo '  </Limit>' >> $ftpc
    echo '  <Limit RETR DELE>' >> $ftpc
    echo '          DenyAll' >> $ftpc
    echo '  </Limit>' >> $ftpc
    echo '</Directory>' >> $ftpc
    echo " " >> $ftpc
    echo " "
done < list

Thanks in advance.

Upvotes: 0

Views: 260

Answers (2)

chepner
chepner

Reputation: 532408

As pointed out in the comments, some command in your loop is reading from standard input. You can either figure out which command that is, and redirect its standard input from /dev/null:

bad_command < /dev/null

or simply use a different file descriptor for the while loop:

while read user rr <&3; do
    ...
done 3< list

Now the read command is not reading from standard input, but from file descriptor 3, which is unlikely to be in use by any command in the body of the loop.


As pointed out by BMW, you need to fix your if statement:

if [ "$rr" = "y" ]; then

The spaces around the equal sign are necessary, as [ is a command, not part of the if syntax, and it requires 3 distinct arguments ($rr, =, and "y"); it will not parse the single string $rr="y" as a comparison. = is preferred with the [ command, as generally == is not the POSIX equality comparison operator. However, bash does allow ==, but also provides a superior command which does not require $rr to be quoted as required for safety with [:

if [[ $rr == y ]]; then    # == or = will work the same

You can save some typing in the last section of your loop by combining the echo statements into a single compound command and redirecting their combined output once:

{
    echo ...
    echo ...
    echo ...
} > "$ftpc"

Another option as pointed out by tripleee, requires only a single call to cat. It spawns an external process, but looks cleaner.

cat > "$ftpc" <<EOF
#$1
<Directory $uhome/res-devres/>
etc
EOF

You could also just echo and a single string with embedded newlines.

echo "#$1
<Directory $uhome/res-devres/>
etc
" > "$ftpc"

Upvotes: 0

BMW
BMW

Reputation: 45343

change from

if [ $rr=="y" ]; then

to

if [ $rr == "y" ]; then

Upvotes: 3

Related Questions