0

I am attempting to iterate through files in target and all sub directories, calculate their hash, and save all this in a file in each sub directory. I paste here only part of the code. The code works, despite spaces in directory names. All files get listed and hashed (the hash command is ## to test quicker)

Only one thing gets me frustrated. I am trying to get counters to increment but that does not work, whatever I do (changing initial to 1 instead of 0 for example) ccctr does not get modified by increments.

ccctr=$ccctr+1
let "ccctr++"
let "ccctr+=1"
let "ccctr=ccctr+1"

do not work either. I searched but could not find solutions.

Please help anyone?

`#!/bin/bash

cd /target

#find all directories including subs
allD=$(find . -type d -print0 | xargs -0 -n 1 echo)

#Create Counter
ccctr=1
echo counter = $ccctr

#go through all directories, caring for names with spaces
echo "$allD" | while read -r a
do 
    #find all files in directory, not recursive, caring for names with spaces, excluding some
    allF=$(find "$a" ! -name '.DS_Store' ! -name '.localized' -maxdepth 1 -type f -print0| xargs -0 -n 1 echo)
    #go through all files
    echo "$allF" | while read -r b
    do 
        let "ccctr=ccctr+1"
        ##shasha=$(shasum -a 512 "$b")
        shasha="$b"
        echo b: $shasha
    done
    echo --------$ccctr total Files Found
done`
Greg
  • 33
  • 6
  • 2
    Pipes create subshells. This is [BashFAQ #24](https://mywiki.wooledge.org/BashFAQ/024). – Charles Duffy Jul 11 '23 at 17:56
  • This it copies all files from a directory to a temp volume, and count them properly, and the counter variable is accessible after the for loop. This looks for files. How would I code that to look for directories instead. And also for files but limiting depth to current directory. Sorry I am trying to display the code properly... "counter=1; for f (./**/*(.NDoN)) { echo " Reading file $counter : $f"; counter=$[$counter+1]; cp $f /Volumes/RAMDisk/tempp }; counter=$((counter-1)); echo $counter" – Greg Jul 11 '23 at 23:24
  • This it copies all files from a directory to a temp volume, and count them properly, and the counter variable is accessible after the for loop. This looks for files. How would I code that to look for directories instead. And also for files but limiting depth to current directory. Sorry I am trying to display the code properly... `counter=1; for f (./**/*(.NDoN)) { echo " Reading file $counter : $f"; counter=$[$counter+1]; cp $f /Volumes/RAMDisk/tempp }; counter=$((counter-1)); echo $counter` – Greg Jul 11 '23 at 23:29
  • Comments are short... So the counter in that example is accessible outside the for loop. As I don't understand that code, I don't know why. – Greg Jul 11 '23 at 23:31
  • The point of that little script to read all files and display their names was to stretch the legs of old archive drives and knowing what file would eventually have I/o errors. – Greg Jul 11 '23 at 23:33
  • I think I should made another post more specific about that code. Hope I'm doing it right, forum rules wise I mean – Greg Jul 11 '23 at 23:33
  • The `for` loop has no pipe. It's specifically **pipe** syntax that create a subshell (and thus limit variable scope). `echo "$allD" | while` is the problem; if you changed it to `while ...; done <<<"$allD"` there'd be no problem. – Charles Duffy Jul 11 '23 at 23:49
  • BTW, you can [edit] your questions after they're created, including when they're closed. – Charles Duffy Jul 11 '23 at 23:50
  • BTW, you have the question tagged bash, but your above comment is using zsh-only syntax. Be sure you tag for the shell you're actually using. – Charles Duffy Jul 11 '23 at 23:51
  • (As another aside, `$[ ... ]` -- like `let` -- is antique 1980s math syntax; ever since POSIX.2 was published in the early 90s, standard syntax for math in shells has been `$(( ... ))`). – Charles Duffy Jul 11 '23 at 23:52
  • Also, `find ... -print0 | xargs -0 -n 1 echo` defeats the _whole point_ of using `-print0`: it makes filenames with literal newlines no longer be handled correctly. If you're going to use NUL-delimited streams, _parse_ them as NUL-delimited streams. In bash, that would be `find ... -print0 | while IFS= read -r -d ''; do ...`, or -- to avoid the bug this question is about -- `while IFS= read -r -d ''; do ...; done < <(find ... -print0)` – Charles Duffy Jul 11 '23 at 23:57
  • Thank you all. I got some points and will work it out. – Greg Jul 12 '23 at 00:15

0 Answers0