问题
I have an interesting problem that I can't seem to find the answer for. I am creating a simple app that will help my dev department auto launch docker containers with NginX and config files. My problem is, for some reason I can't get the bash script to store the name of a folder, while scanning the directory. Here is an extremely simple example of what I am talking about....
#!/bin/bash
getFolder() {
local __myResultFolder=$1
local folder
for d in */ ; do
$folder=$d
done
__myResultFolder=$folder
return $folder
}
getFolder FOLDER
echo "Using folder: $FOLDER"
I then save that simple script as folder_test.sh and put it in a folder where there is only one folder, change owner to me, and give it correct permissions. However, when I run the script I keep getting the error...
./folder_test.sh: 8 ./folder_test.sh: =test_folder/: not found
I have tried putting the $folder=$d
part in different types of quotes, but nothing works. I have tried $folder="'"$d"'"
, $folder=`$d`
, $folder="$d"
but none of it works. Driving me insane, any help would be greatly appreciated. Thank you.
回答1:
The culprit is the line
$folder=$d
which is treating the folder names to stored with a =
sign before and tried to expand it in that name i.e. literally treats the name =test_folder/
as an executable to be run under shell but does not find a file of that name. Change it to
folder=$d
Also, bash
functions' return value is only restricted to integer types and you cannot send a string to the calling function. If you wanted to send a non-zero return code to the calling function on $folder
being empty you could add a line
if [ -z "$folder" ]; then return 1; else return 0; fi
(or) if you want to return a string value from the function, do not use return
, just do echo
of the name and use command-substitution with the function name, i.e.
getFolder() {
local __myResultFolder=$1
local folder
for d in */ ; do
folder=$d
done
__myResultFolder=$folder
echo "$folder"
}
folderName=$(getFolder FOLDER)
echo "$folderName"
回答2:
If you want to save your result into a named variable, what you're doing is called "indirect assignment"; it's covered in BashFAQ #6.
One way is the following:
#!/bin/bash
# ^^^^ not /bin/sh; bash is needed for printf -v
getFolder() {
local __myResultFolder=$1
local folder d
for d in */ ; do
folder=$d
done
printf -v "$__myResultFolder" %s "$folder"
}
getFolder folderName
echo "$folderName"
Other approaches include:
Using
read
:IFS= read -r -d '' "$__myResultFolder" < <(printf '%s\0' "$folder")
Using
eval
(very, very carefully):# note \$folder -- we're only trusting the destination variable name # ...not trusting the content. eval "$__myResultFolder=\$folder"
Using
namevar
s (only if using new versions of bash):getFolder() { local -n __myResultFolder=$1 # ...your other logic here... __myResultFolder=$folder }
来源:https://stackoverflow.com/questions/41450156/saving-function-output-into-a-variable-named-in-an-argument