The above appears to work fine, however, the problem arises with loop 3
loop3
genvar=�pattern�
iteration=�002�
eval varcontents=�\$genvar�_�$iteration�
expected results varcontents=�*�
actual results are an error pattern_002: parameter not set
I realise what is happening and can resolve the problem by using pattern_002=\* in the config file. The problem is that the file is user created and it may be that someone will forget the backslash before the *.
Can someone suggest a way to resolve this so that a * without a backslash can be used in the configuration file please?
To preserve characters with a special meaning to the shell you have to protect them - usually by quoting them. Without knowing your actual code: if using \* instead of * solves your problem chances are that somewhere in your script you use your variable containing the asterisk without quoting: $variable instead of "$variable".
I suggest you look carefully through your code for such occasions, it might very well solve your problem.
Apologies, I may have been a bit hasty in suggesting that in that way. noglob prevents wildcard characters from being expanded.
I don't know exactly how you'll be extracting your variables from the file or using them in your script, but here's a bit of code which uses eval in a similar way to the way you seem to need it and allows the asterisk character to be preserved:-
#!/bin/ksh
set -o noglob
pattern_002=*
set +o noglob
echo "PATTERN $pattern_002"
the eval-statement will surely leave the asterisk unprotected. In this case the only way to deal with it is to escape it in the script itself:
'sed s/\*/\\&/g'
Hope this helps even better. ;-))
PS: "noglobber" or the equivalent parameter "-f" prevents filename substitution. The problem is that an "eval ..." might take precedence (i have never tested that).
Thanks for your reply. The pattern may not always be a * so I could not run sed on it every time. I cannot check to see if the pattern is a * as it has already been evaluated!
I think the issue with variable-expansion and noglob is only a problem when doing your 'eval'. Setting noglob to on shouldn't affect it otherwise. I think I'm roughly using your code-structure in the following:-
if [ $v_search_return_code -eq 0 ]
then
v_search_return=`grep ^"$p_search_item"_"$p_iteration" ./paramfile`
set -o noglob
v_search_line=`print ${v_search_return#*=}`
echo "PATTERN $v_search_line"
set +o noglob
return 0
fi
}
v_search=pattern
v_iter=002
fn_read_config "$v_search" "$v_iter"
set -o noglob
echo "PATTERN $v_search_line"
set +o noglob
And I'm still able to get the output:-
PATTERN *
PATTERN *
I suppose it could depend on how you were using the resulting variable value, but I'm guessing it could still be possible by manipluating noglob.
Maybe i don't get your point, but in the code snippet you provided i see several occasions where a quote would help. I tried the following code and it worked for every special char i tried in the input file - even without setting noglob. It should cover all the operations you used in your script save for the eval:
#!/bin/ksh
function func {
typeset var1="$1"
typeset var2="$2"
print - "Output from func(): var1=\"$var1\"\tvar2=\"$var2\""
return 0
}
# main()
typeset mvar1=""
typeset mvar2=""
cat input_file_with_codes | while read line ; do
mvar1="$(print - "$line" | sed 's/ */ /g' | cut -d' ' -f1)"
mvar2="$(print - "$line" | sed 's/ */ /g' | cut -d' ' -f2)"
print - "mvar1=\"$mvar1\"\tmvar2=\"$mvar2\""
func "$mvar1" "$mvar2"
done
exit 0
To write a small sed function which escapes every special character for exactly the eval should be no problem:
#!/bin/ksh
function escape_it {
typeset input="$1"
typeset output=""
output="$(print - "$input" | sed 's/[*?|]/\\&/g')"
print - "$output"
return 0
}
# main()
# ... do whatever ...
tmpvar="$(escape_it "$var")"
eval $tmpvar
# ... rest of your code ...
exit 0
Thank-you both for your help. In the end I pre-parsed the config file with the sed statement to escape any special characters. I then used the resulting output as the config file. This worked fine.
Many thanks for all your time and patience!
Cheers
Helen