This is really over-thought.
#!/usr/bin/env bash
IFS='
'
select x in $(cd /some/data/directory && du -sh -- *); do
break
done
unset IFS # or save/restore it explicitly
As an added bonus, the only bashism here is the select
.
Typescript:
$ ./cg
1) 0 0
2) 0 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
3) 0 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
4) 0 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a
5) 0 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ą
6) 60k 1028501896.pdf
7) 0 a
8) 16k a.bkp
9) 36k a.cpio
10) 10k a.d
11) 36k a.patch
12) 60k a.pax
13) 84k a.png
14) 4k b.cpio
15) 32k b.pax
16) 12k b.tar
17) 0 bugreport.cgi?bug=910770;mbox=yes;mboxmaint=yes
18) 74.2M build-output
19) 796k busybox
20) 428k busybox_1%3a1.30.1-6+b3_amd64.deb
21) 0 CB_Unix
22) 4k cg
#?
The quoting like you're doing doesn't work because quote removal applies only to the original word; the result of parameter expansion is only field-split (and globbed). To do that, you need to tokenise the string as input:
eval "select x in $sel
do
break
done"
and for obvious reasons you really shouldn't do this, since you haven't actually escaped the filenames:
$ ./cg
./cg: eval: line 11: unexpected EOF while looking for matching `''
./cg: eval: line 15: syntax error: unexpected end of file
if you really need to fork a process for each line and really need to store the du output in a big string then you should've done
#!/usr/bin/env bash
sel=
while read -r l; do
sel="$(printf '%s %q' "$sel" "$l")"
done < <(cd /some/data/directory && du -sh -- *)
eval "select x in $sel; do
break
done"
(I've disabled escape-mangling the paths, which you had on for some reason.)
select
see multiple words. Use an array instead, see How can we run a command stored in a variable? and also Why does my shell script choke on whitespace or other special characters? – ilkkachu Jan 06 '23 at 11:40