Error in shell script
-
13-06-2021 - |
Pergunta
I'm using a shell script to help me resolve library paths so I can send out my app bundle. I don't know much about shell scripts and was hacking something together from other pieces so I really don't know how to resolve the issue. The issue revolves around lines like done << ...
Here's some code! Note, this is based off of a Qt project.
echo "Below is the list of install_name_tools that need to be added:"
while IFS= read -r -d '' file; do
baseName=`basename "$file"`
#echo "otool -L \"$file\" | grep -e \"*$baseName\""
hasUsrLocal=`otool -L "$file" | grep -v -e "*$baseName" | grep -v libgcc_s.1.dylib | grep -v libstdc++.6.dylib | grep "/usr/local\|/Users"`
if [ -n "$hasUsrLocal" ]; then
#echo "WARNING: $file has /usr/local dependencies"
#echo "\"$hasUsrLocal\""
#echo "To Fix:"
while read line; do
#Remove extra info
library=`echo "$line" | perl -pe 's/(.*?)\s\(compatibility version.*/\1/'`
libraryBaseName=`basename "$library"`
frameworkNameBase="$libraryBaseName.framework"
isframework=`echo "$library" | grep "$frameworkNameBase"`
unset fixCommand;
if [ -n "$isframework" ]; then
#Print out how to fix the framework
frameworkName=`echo $library | perl -pe "s/.*?($frameworkNameBase\/.+)/\1/"`
fixCommand=`echo "install_name_tool -change \"$library\" \"@executable_path/../Frameworks/$frameworkName\" \"$file\""`
else
#Print out how to fix the regular dylib
if [ "$baseName" != "$libraryBaseName" ]; then
fixCommand=`echo "install_name_tool -change \"$library\" \"@executable_path/../Frameworks/$libraryBaseName\" \"$file\""`
fi
fi
echo "$fixCommand"
done << (echo "$hasUsrLocal")
#echo "---------------------------------------------------------"
fi
done << (find MyProgram.app -type f -print0)
The error this prints is referring to the line done << (echo "$hasUsrLocal")
./deploy.sh: line 563: syntax error near unexpected token `('
./deploy.sh: line 563: ` done << (echo "$hasUsrLocal")'
I'll get a similar issue for done << (find MyProgram.app -type f -print0)
too if I comment out some of the script. Thank you!
Solução
I believe the author intended to use a process substitution:
done < <( find ...
You could also try piping the find into the while loop:
find MyProgram ... | while IFS= read -r -d '' file; do ... done
Outras dicas
I fixed it! Thanks to William Pursell for the keyword "process substitution." That gave me ground to "Google."
I noticed it was a spacing issue. Needs to be spaced like done < <(echo "$hasUsrLocal")
for example!
Answer
The <<
symbol is for here-documents. What you probably want is redirected process substitution:
< <( : )
The <(command_list)
construct is for process substitution, while the first less-than symbol redirects standard input of your loop to the file descriptor created by the process substitution that follows it on the line.
Pro Tip
This is a handy but confusing syntax. It really helps to read it from right to left.