Reputation: 148
I made little piece of code to describe my problem.
#!/bin/bash
function writeToFile(){
echo "$1" >> file.txt
}
function checkLetters(){
letters_array+=( $1 )
count=0
for letter in ${letters_array[*]}
do
if [[ "$1" == "$letter" ]]
then
count=$((count+1))
fi
done
value=1
if [[ $count -eq $value ]]
then
writeToFile "$1"
fi
echo "return"
}
letters=( a b c d e )
for i in {1..2}
do
for letter in ${letters[*]}
do
checkLetters $letter
done
done
file="/mnt/file.txt"
while IFS= read -r line
do
printf "$line\n"
done <"$file"
`> file.txt`
So code is writing letters to file if there is not yet same letter in file. If code is working properly, in file there must be letters a,b,c,d,e and there is if I use code like above. But I need return value from function so I change
checkLetters $letter
to this:
return_value=$(checkLetters $letter)
Now my file is containing a,b,c,d,e,a,b... Why? Why returning value is causing that and how to get that work properly?
Upvotes: 0
Views: 38
Reputation: 2970
Because the command (in this case the function checkLetters
) is executed in a subshell, which inherits the existing letters_array
but only updates its local copy.
Form the bash(1) manual page:
Bash performs the expansion by executing command in a subshell environment and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting. The command substitution $(cat file) can be replaced by the equivalent but faster $(< file).
So exactly the same would happen if you would use
( checkLetters $letter; )
Example:
arr=( )
function test() {
arr+=( $1 )
echo "in test ($1): ${arr[*]}"
}
test 1; test 2;
echo ${arr[*]}
echo "substitution: $(test 3)"
echo "After command substitution: ${arr[*]}"
( test 5; echo "in subshell: ${arr[*]}"; )
echo "after subshell: ${arr[*]}"
results in:
in test (1): 1
in test (2): 1 2
1 2
substitution: in test (3): 1 2 3
After command substitution: 1 2
in test (5): 1 2 5
in subshell: 1 2 5
after subshell: 1 2
Upvotes: 1