I am writing a bash function to get all git repositories, but I have met a problem when I want to store all the git repository pathnames to the array patharray
. Here is the code:
gitrepo() {
local opt
declare -a patharray
locate -b '\.git' | \
while read pathname
do
pathname="$(dirname ${pathname})"
if [[ "${pathname}" != *.* ]]; then
# Note: how to add an element to an existing Bash Array
patharray=("${patharray[@]}" '\n' "${pathname}")
# echo -e ${patharray[@]}
fi
done
echo -e ${patharray[@]}
}
I want to save all the repository paths to the patharray
array, but I can't get it outside the pipeline
which is comprised of locate
and while
command.
But I can get the array in the pipeline
command, the commented command # echo -e ${patharray[@]}
works well if uncommented, so how can I solve the problem?
And I have tried the export
command, however it seems that it can't pass the patharray
to the pipeline.
To find it, you can search for “Append to array variable” action or go to “Built-in”: You won't probably see it in the main options, so you'll need to expand until you dine the “Variable” group. Pick “Variable.” Select the “append to string variable” action.
When you want to add an element to the end of your array, use push(). If you need to add an element to the beginning of your array, try unshift(). And you can add arrays together using concat().
The <(COMMAND) is called process substitution. It makes the output of the COMMAND appear like a file. Then, we redirect the file to standard input using the < FILE. Thus, the readarray command can read the output of the COMMAND and save it to our my_array.
Bash runs all commands of a pipeline in separate SubShells. When a subshell containing a while
loop ends, all changes you made to the patharray
variable are lost.
You can simply group the while
loop and the echo
statement together so they are both contained within the same subshell:
gitrepo() {
local pathname dir
local -a patharray
locate -b '\.git' | { # the grouping begins here
while read pathname; do
pathname=$(dirname "$pathname")
if [[ "$pathname" != *.* ]]; then
patharray+=( "$pathname" ) # add the element to the array
fi
done
printf "%s\n" "${patharray[@]}" # all those quotes are needed
} # the grouping ends here
}
Alternately, you can structure your code to not need a pipe: use ProcessSubstitution
( Also see the Bash manual for details - man bash | less +/Process\ Substitution
):
gitrepo() {
local pathname dir
local -a patharray
while read pathname; do
pathname=$(dirname "$pathname")
if [[ "$pathname" != *.* ]]; then
patharray+=( "$pathname" ) # add the element to the array
fi
done < <(locate -b '\.git')
printf "%s\n" "${patharray[@]}" # all those quotes are needed
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With