2

I have the following:

 #!/bin/bash a=0 for d in ./*/ ; do ( cd "$d" ((a++)) echo $a ); done 

Which goes into each directory in my path, increments a and prints a. However, the output is always 1. Why is that?

2 Answers 2

5

From bash(1):

 (list) list is executed in a subshell environment (see COMMAND EXECU‐ TION ENVIRONMENT below). Variable assignments and builtin com‐ mands that affect the shell's environment do not remain in effect after the command completes. The return status is the exit status of list. 

By simply removing the parenthesis you have around that block of code, you would have something like this:
#!/bin/bash a=0 for d in ./*/ do ((a++)) echo $a done 

(also slightly more conventionally formatted)

the result is:

1 2 3 4 5 6 7 
4
  • The one liner quick and working for d in `seq 1 3`;do echo $d ;done to not pollute the interactive shell and without $a which is not needed. If needed: a=0;for d in `seq 1 3`;do echo $a ;((a++));done Commented Oct 29, 2020 at 12:32
  • @Timo How does this relate to the question, though? The question is about some set of files. Commented Oct 29, 2020 at 12:47
  • 1
    @Timo Ok, I restored the file pattern from the question as I guess that difference is what caused your confusion. Commented Oct 30, 2020 at 13:36
  • 1
    No worries, I got your idea. The question is about traversing a dir but more important about the increment. Your answer is correct. Commented Oct 30, 2020 at 14:47
2

Because you put the loop body in unnecessary ()'s which makes it execute in a subshell if I recall correctly.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.