1

When using the following command within a bash array, it loses the line separation of the array elements.

array=$(find "${PWD%/*}" -name '*.dmg')

If I redirect the path of the find command, without storing it in a variable, but storing it to a text file, it gives the desired result.

find "${PWD%/*}" -name '*.dmg' > Out.txt

But I would like to use the result as a variable in Bash and to loop through it. In this case the find command should return an array with the path of all .dmg files in a directory. I want to loop through this array with the hdiutil mount command in order to mount all the .dmg files in the directory.

stephanmg
  • 746
  • 6
  • 17
AFouquet
  • 43
  • 6

1 Answers1

3

You can use mapfile to safely transfer your found files into an array.

#!/usr/bin/env bash
declare -a array

mapfile -d '' array < <(find "${PWD%/*}" -name '*.dmg' -print0 2>/dev/null)

find -print0 option produces null delimited strings so spaces, tabs and carriage return in file names are preserved safely.

mapfile -d '' array reads stdin with a null delimiter to populate array

< <(commands group) injects the commands group's output into the stdin of the other commands group.

The result is, that the output of find is mapped into array.

For older Bash 3.2 from MacOS lacking mapfile, here is an alternate way to populate array:
#!/usr/bin/env/bash

declare -a array

while read -r -d ''; do
    array+=("$REPLY")
done < <(find "${PWD%/*}" -name '*.dmg' -print0 2>/dev/null)
Léa Gris
  • 17,497
  • 4
  • 32
  • 41
  • I will try it out, will get back to you, after I get the result. Thank you :) – AFouquet Nov 15 '19 at 16:25
  • Just learned that I don't have the mapfile command in OSX. I will have to find an alternative to this. I probably could download it with homebrew, than every system where the script should run would have to install it first in order for it to work. – AFouquet Nov 15 '19 at 16:33
  • @AFouquet If you want something that works on any macOS system, consider writing this in `zsh` instead. – chepner Nov 15 '19 at 16:36
  • @chepner I am very new to scripting in general. What are the advantages of using zsh? – AFouquet Nov 15 '19 at 16:41
  • It's mainly designed with interactive usage in mind. However, for your purposes, its main benefit is that even versions of `zsh` that ship with older versions of macOS (and some version has shipped with macOS for a very long time, though I don't have any reference for what shipped when) provide more "continuity" of features with modern `zsh` than you see with `bash` 3 vs `bash` 4.x. – chepner Nov 15 '19 at 16:46
  • 1
    Put another way: the chances of an appropriate version of `zsh` (that can easily support reading the output of `find` into an array) being preinstalled on your target machines is greater than an appropriate version of `bash`. – chepner Nov 15 '19 at 16:57
  • @AFouquet I added an alternative method compatible with Bash 3.2 from MacOS – Léa Gris Nov 15 '19 at 18:04
  • @chepner I will definitely look in to zsh. Thank you. – AFouquet Nov 15 '19 at 19:03
  • @LéaGris Will also try out your alternative thank you. I'll let you know as soon as I get a result. Thank you for the support. :) – AFouquet Nov 15 '19 at 19:04
  • Note that in `zsh` or recent enough `bash`; you don't need `find`; `array=( $PWD/**/*.dmg )` would suffice. (And `zsh` globs have enough bells and whistles that can replace even complicated uses of `find`.) – chepner Nov 15 '19 at 19:17
  • @LéaGris Hi, I have finely completed my scrpit. It's not perfect yet, but it does what it is supposed to. Thank you for your help. Here is the github Link if you would like to check it out and give me some feedback. I would really appreciate it. https://github.com/afouquet7/Bash-.dmg-Installer/blob/release/TheInstallator_v1.3.command – AFouquet Jan 09 '20 at 10:50