3

In Bash if I want to get a list of all available keyboard layouts but prepend my own keyboard layouts I can do:

readarray -t layouts < <(localectl list-x11-keymap-layouts)
layouts=("custom1" "custom2" "${kb_layouts[@]}")

If I want to append I can do:

readarray -t layouts < <(localectl list-x11-keymap-layouts)
layouts=("${kb_layouts[@]}" "custom1" "custom2")

Is it possible to achieve the same in a single line, in the readarray command?

user5507535
  • 1,580
  • 1
  • 18
  • 39
  • You want to append to array `layouts` that is already populated by the `localectl` command? – Inian Nov 11 '20 at 08:29
  • @Inian Yes, but do it at the same time, I mean prepend the custom values with the same `readarray` command. I tried different ways but it didn't work. I don't know if it's possible. – user5507535 Nov 11 '20 at 08:34
  • To append to an array, you can use `+=` --> `layouts+=(custom1 custom2)` – glenn jackman Nov 11 '20 at 14:34

2 Answers2

6

You can use the -O option to mapfile/readarray to specify a starting index. So

declare -a layouts=(custom1 custom2)
readarray -t -O"${#layouts[@]}" layouts < <(localectl list-x11-keymap-layouts)

will add the lines of the command starting after the existing values in the array instead of overwriting the existing contents.

You can append multiple values at once to an existing array with +=(...):

readarray -t layouts < <(localectl list-x11-keymap-layouts)
layouts+=(custom1 custom2)
Shawn
  • 47,241
  • 3
  • 26
  • 60
4

Since the process substitution output <(..) is replaced by a FIFO for the processes to consume from, you can add more commands of choice inside. E.g. to append "custom1" "custom2" you just need to do

readarray -t layouts < <(
  localectl list-x11-keymap-layouts; 
  printf '%s\n' "custom1" "custom2" )

This creates one FIFO with contents from both the localectl output and printf output, so that readarray can read them as just another unique non-null lines. For prepend operation, have the same with printf output followed by localectl output.

Inian
  • 80,270
  • 14
  • 142
  • 161