bashfor-loopzshqpdf

Using Zsh and QPDF to decrypt multiple PDFs


From this answer https://stackoverflow.com/a/59688271/7577919 I was able to decrpypt multiple PDFs in place using this bash script:

temp=`ls`; 
for each in $temp;
do qpdf --decrypt --replace-input $each;  
done

However, I had initially attempted to do this in Zsh (as it's encouraged in MacOS 10.15 Catalina), but was unable. It gave an error of output: File name too long

What is the difference between the for loops in Bash and Zsh and how would I go about writing a proper Zsh script?


Solution

  • There is no difference in the for-loop, but in the way variables are expanded. Consider this program:

    x='a b'
    for v in $x
    do
      echo $v
    done
    

    In bash, $x would word-split into 2 arguments, and hence the loop would be executed twice, once for a and once for b. In zsh, $x would not undergo word-splitting and the loop would be executed once, for the valud a b. This difference is everywhere when you expand a parameter.

    In your case, the loop is executed once, each holding the complete output of the ls statement.

    Of course in your case, it would be simpler in zsh to write the loop as

    for each in *(N)
    

    but if you really need a variable, I would use an array:

    temp=(*(N))
    

    The N-flag after the wildcard takes care that you get an empty string instead of an error message, if there are no files.

    If you also want to catch the dot-files (similar to what a ls -A would do), use (ND) instead.