1

I came across a problem that I am trying to solve and I was not able to find a definitive google search result for what I am trying to do. I have not done many for loops in bash and maybe I am abusing it a bit.

I am trying to solve an issue where i is certain line that is returned form a simple one liner and associate a counter with it.

One liner format:

 n=0; for i in $( ls /dev/ | grep sd | awk '!/a/' ); do ( n=$(($n+1)); ( pvs | grep $i ) > /dev/null && echo /dev/$i configured || ( echo $n $i || ( echo "ERROR ADDING SECONDARY DRIVES ( /dev/$i )"; ) ) ); done; echo $n;

Expanded Format:

n=0;
for i in $( ls /dev/ | grep sd | awk '!/a/' );
do (
   n=$(($n+1));
   ( pvs | grep $i ) > /dev/null && echo /dev/$i configured
      || (
         echo $n $i
         || (
            echo "ERROR ADDING SECONDARY DRIVES ( /dev/$i )";
            )
         )
   ); 
done; 
echo $n;

Output:

/dev/sdb configured
/dev/sdc configured
1 sdd
1 sde
1 sdf
1 sdg
0

Desired output:

/dev/sdb configured
/dev/sdc configured
1 sdd
2 sde
3 sdf
4 sdg
4

The issue that I seem to be running into is that at the beginning of the second and subsequent loops the variable n is reset to its initial value of 0

This would greatly help me to create directories /data(1..n) as well as create independent volume groups and logical volumes.

I only have /dev/sdc /dev/sdb as true hard drives, drives /dev/sde... were temporary created using the touch command.

Thank you all for your time.

-Robert

1
  • 1
    You do not need to use variable expansion ($i) inside arithmetic evaluation ($(( ))), just use the variable name (i). Commented Oct 31, 2015 at 21:43

3 Answers 3

3

The highlights of the changes I made, are:

  • Try to list the interesting devices without grep and awk;
  • Remove the parentheses for the do-done body, that would result in a subshell
  • add 1 to n using n++;
  • Explicit use of if-statement, so your friends can see what you are doing;
  • Removed the echo "ERROR ADDING .. that would be called in your code when the echo $n $i fails.
  • (EDIT: I made the code too short, gave a bad example forgetting double quotes)
    Use quotes around all vars avoiding future mistakes. Some day your var will contain spaces, wildcards, whatever and you would wish you had trained to use double quotes whenever possible. The quotes can be far away (as in the echo commands), but close enough so that the value of the var doesn't get interpreted.

Please continue with this code as a starter:

n=0
for i in /dev/sd[^a]*; do
   ((n++))
   if /sbin/pvs | grep -q "$i"; then
      echo "/dev/$i configured"
   else
      echo "$n $i"
   fi
done
echo "\$n after loop: $n"
Sign up to request clarification or add additional context in comments.

1 Comment

Tx. I changed the code according to your suggestions. I thought I read ksh somewhere, that must have been another question.
2

You've got some extra unneeded parentheses in there that are executing a subshell I believe, where the subshell value of $n is local (does not get exported). (Some other parentheses are also unneeded, and the semicolons are also redundant in the multiline version).

n=0
for i in $( ls /dev/ | grep sd | awk '!/a/' )
do
   n=$(($n+1))
   ( pvs | grep $i ) > /dev/null && echo /dev/$i configured
      ||
         echo $n $i
         ||
            echo "ERROR ADDING SECONDARY DRIVES ( /dev/$i )"
done
echo $n

It also looks bit odd that you would do that awk '!/a/' right after a grep, when grep -v a is semantically identical (isn't it?).

Comments

0

Extra parenthesis were my issue however, however Walter A's answer had simplistic format that I think is more reliable than my submitted code.

Thank you both for your time. I will up-vote both of you when I am allowed to.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.