Home > OS >  Store the results of "find" in an array (without using read)
Store the results of "find" in an array (without using read)

Time:03-08

I'm trying to recreate the script from this answer but without using read. I tried something like:

pids=()
for i in $(find /mnt/c/Projekte/test/pids/ -iname "*.pid")
do
    pids =("$i")
done

declare -p $pids

But that only results in this:

./test.sh: line 9: declare: /mnt/c/Projekte/test/pids/a1.pid: not found

The test folder I created looks like this:

-rwxrwxrwx 1 vitus vitus   0 Mar  2 16:54 a1.pid
-rwxrwxrwx 1 vitus vitus   0 Mar  2 16:54 a2.pid
-rwxrwxrwx 1 vitus vitus   0 Mar  2 16:54 a3.pid
-rwxrwxrwx 1 vitus vitus  61 Mar  2 16:54 fill.sh
-rwxrwxrwx 1 vitus vitus 121 Mar  8 11:48 test.sh

CodePudding user response:

If you've got Bash 4.0 or later you can reliably populate the pids array without using find. Try this Shellcheck-clean code:

#! /bin/bash -p

shopt -s dotglob
shopt -s globstar
shopt -s nocaseglob
shopt -s nullglob

pids=( /mnt/c/Projekte/test/pids/**/*.pid )

declare -p pids
  • shopt -s dotglob enables globs to match files and directories that begin with .. find shows such files by default.
  • shopt -s globstar enables the use of ** to match paths recursively through directory trees.
  • shopt -s nocaseglob causes globs to match in a case-insensitive fashion (like find option -iname versus -name).
  • shopt -s nullglob makes globs expand to nothing when nothing matches (otherwise they expand to the glob pattern itself, which is almost never useful in programs).
  • The shopt commands can be combined into one if preferred: shopt -s dotglob globstar nocaseglob nullglob.
  • Note that this code might fail on versions of Bash prior to 4.3 because symlinks are (stupidly) followed while expanding ** patterns.

CodePudding user response:

To print a variable pass variable name.

declare -p pids

Using a loop on word-splitted result of a command to then properly quote it when adding to an array is odd. Just load it straight to an array.

 pids=($(find ....))

Note that you might want to set IFS=$'\n' before word splitting takes place, and you might want to research quoting and word splitting and filename expansion in shell.


Either way, you should do something along:

readarray -d '' -t pids < <(find /mnt/c/Projekte/test/pids/ -iname "*.pid" -print0)

or with while loop:

while IFS= read -r -d '' a; do
   pids =("$a")
done < <(find /mnt/c/Projekte/test/pids/ -iname "*.pid" -print0)

See https://mywiki.wooledge.org/BashFAQ/001

  •  Tags:  
  • bash
  • Related