On Mon, Oct 09, 2023 at 01:32:07PM +0200, Laszlo Ersek wrote:
>> Shell arrays are
>> a bash-specific feature, and the extent array is deeply ingrained. See
>> especially commit df63b23b6280 ("log: Use strict shell quoting for every
>> parameter displayed in the log file.", 2021-01-04). In particular the
>> assignment
>>
>> extents=(0x0 0x8000 "hole,zero" 0x8000 0x8000 "")
>>
>> turns "extents" into an array variable.
>>
>> In the bug tracker, comment
>> <
https://aur.archlinux.org/packages/nbdkit#comment-937375> says,
"Thus
>> this is an upstream issue; their scripts are calling sh when they should
>> be calling bash". I think that's correct; for logscript=..., we should
>> require /bin/bash in the manual, and execute the script with /bin/bash
>> explicitly, not just system().
>
> This would create a runtime dependency from nbdkit to /bin/bash which
> I'd like to avoid.
The runtime dependency is already there in our logscript interface; the
name=(a b c ... z)
syntax is already bash-only, for defining a shell array.
The man page for nbdkit-log-filter does not mention extents=()
anywhere, and exports=("") is only shown as a single sample log
output, without mention in the LOG SCRIPT section. I checked both
1.34.4 I have pre-installed on Fedora 38, and
filters/log/nbdkit-log-filter.pod at the top of development. Merely
stating "Strings and lists are shell-quoted." or that "Other
parameters like C<offset=N> are turned into shell variables C<$offset>
etc." does not properly describe which items passed to the logscript
will actually be lists under which exported names, whether or not we
choose to stick to bash-only syntax. So we already have a bug that
our documentation is incomplete; and therefore, if we change what we
output, we can also use that as a chance to rectify our documentation
bug to what we really want to support.
So the question is basically how to best emulate an array in the POSIX
shell. Some (rough) options that occur to me:
- Use named variables such as name_0, name_1, name_2, ... and so on.
Requires eval tricks, and if the array is large, it creates many
variables, which some shells (?) may have issues with.
If we're going to run out of memory from having too many strings to
pass through all extents information through the environ, we will do
so whether we do it as a single array variable or as multiple
individual variables.
- Generate a shell function with a huge case statement; like "get_name
0" should print "a", "get_name 1" should print "b",
etc. The caller
would then do
element=$(get_name $idx)
We'd also need to define something like $extents_max=N so that the
script can get correct bounds for the loop it writes around the
$(get_name $idx) calls.
- write the elements of the array to a text file (one, quoted, element
per line), and then use a combination of "tail" and "head" for
fetching
the right line. Incredibly slow, of course.
... I'm sure stackoverflow has further / better ideas for emulating
arrays in the POSIX shell.
And then, because keeping the current (fast, but nonportable) solution
would be nice, we should probably add a new argument for the log filter,
"compat" or "posix" or some such, which would select the more
restricted
interface.
Yes, having a way to fine-tune what we output for the scripts
consumption would be nice, and perhaps extensible (JSON output,
anyone?).
--
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:
qemu.org |
libguestfs.org