Re: [live-build] "E: Unable to find a source package for syslinux,grub-efi"
On Wed, 11 Mar 2020 at 05:52, <jnqnfe@gmail.com> wrote:
> On Tue, 2020-03-10 at 15:38 +0000, jnqnfe@gmail.com wrote:
> > obviously it seems to be treating "syslinux,grub-efi" as a single
> > package name which is wrong. this string originates from
> > LB_BOOTLOADERS.
> >
> > the code that should be handling this in source_debian looks to be
> > the
> > following:
> > ```
> > echo "${LB_BOOTLOADERS}" | \
> > while IFS="," read -r BOOTLOADER
> > do
> > echo "${BOOTLOADER}" >> source-selection.txt
> > done
> > ```
> >
> > which is correctly specifying a comma as the separator, so if this is
> > where the problem originates, I don't know why...
Hi,
There's several issues to know about here.
First issue is that different shells, such as bash and dash, have
different syntax and behaviour. So this code must be tested in all
shells where it is expected to run.
Next issue is that the shell builtin command 'read' does not work the
way you seem to think. From the 'dash' manpage:
"""
read [-p prompt] [-r] variable [...]
[...] a line is read from the standard input. [...] and the line is
split [...], and the pieces are assigned to the variables in order. At
least one variable must be specified. If there are more pieces than
variables, the remaining pieces (along with the characters in IFS that
separated them) are assigned to the last variable.
"""
Demo code illustrating the final sentence I quoted there:
printf '%s\n' "a1,a2,a3,a4" "b1,b2,b3,b4" | \
while IFS="," read -r v1 v2 v3; do
printf '%s\n' "v1:${v1} v2:${v2} v3:${v3}"
done
The above demo code tested in 'dash' produces output:
v1:a1 v2:a2 v3:a3,a4
v1:b1 v2:b2 v3:b3,b4
Next issue is that there are subtle behaviour differences between
IFS='' and IFS unset. So those two states must be handled separately
when when modifying and restoring IFS
One approach is to use a subshell-function so that its local IFS can
be modified without affecting the IFS in the parent shell.
Demo code:
mysubshell() (
# use the IFS of this subshell-function to split $1 into $@
IFS=,
set -o noglob
set -- $1
set +o noglob
for s in "$@" ; do echo "${s}" ; done
)
mysubshell a1,a2,a3,a4
The above demo code tested in 'dash' produces output:
a1
a2
a3
a4
But that requires a subshell.
To restore IFS state correctly without using a subshell involves
detecting when IFS is unset.
Demo code:
# some test values for IFS
# IFS=
# unset IFS
# IFS=foo
# display IFS
printf '%s' "IFS="
/usr/bin/printf '%q' "${IFS-unset}"
printf '\n'
# remember IFS
remember_ifs=${IFS-__flag__ifs-is-unset__}
# change IFS for some purpose
IFS=bar
# restore IFS
case "${remember_ifs}" in
__flag__ifs-is-unset__ )
# IFS was unset, so restore that state
unset IFS
;;
* )
# restore the remembered value of IFS
IFS=${remember_ifs}
;;
esac
# display IFS
printf '%s' "IFS="
/usr/bin/printf '%q' "${IFS-unset}"
printf '\n'
The above demo code tested in 'dash' produces output:
initial IFS=' '$'\t\n'
restore IFS=' '$'\t\n'
That result is for the default value of IFS in 'dash'.
Uncomment various "test values for IFS" lines in the code
to demo how it handles those other initial values of IFS.
Reply to: