Bash: shell quoting

Another issue I had during the weekend that took me hours. Thanks that I have been reading a bit this book (1.6) and had some clues.

I was trying to test a repo to start an Arista lab using docker and I assumed that everything should work if I followed the instructions. My problem was the script trying to push some basic config to the switches.

This is was the initial function:

#!/usr/bin/env bash
...
function fast_cli() {
  params="${*:2}"
  commands="${params//;/\\\n}"
  docker exec "${1}" bash -c "echo -e ${commands} | FastCli -p15 -e
}
...

If you type that command in a bash shell directly is something like this:

$ docker exec DOCKER_ID bash -c 'echo -e "configure\n hostname sp01\n end\n write\n" | FastCli -p15 -e'

As you can see that differs with what we have inside the bash script. So from the bash script we need to put between ‘ the parameter for -c but inside the parameter we need to use “. So I had to make the change below:

-  docker exec "${1}" bash -c "echo -e ${commands} | FastCli -p15 -e"
+  # need to update this command as the quoting doesnt work in my bash
+  docker exec "${1}" bash -c 'echo -e '"'${commands}'"' | FastCli -p15 -e'

The books says Enclose a string in single quotes ‘ unless it contains elements that you want the shell to interpolate. So let’s divide the solution in parts so can be easier to digest (and remember for me in the future because this will bit me again for sure)

  • 1st part: ‘echo -e ‘
  • 2nd part:
  • 3rd part: ‘${commands}’
  • 4th part:
  • 5th part: ‘ | FastCli -p15 -e’

The ” need to be outside the ‘ region because the commands need to be between ” for the docker command. The 3rd part will expand the variable commands.

I guess the author is using a different version of bash? This is mine

$ bash --version
GNU bash, version 5.0.16(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 

This is free software; you are free to change and redistribute it.

LVM 102: pvresize

Something very basic but took me several hours to workout. I had a VM that I wanted to increase a VG as I wanted to create a new LV. I increased the partition in the host server so the PV of the VG had the extra space, but then I couldnt see the increase inside the VM:

[root@HOST]# lvs
  LV      VG  Attr  LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  vm_data vg_os -wi-ao---- 300.00g

[root@VM]# pvs
  PV         VG      Fmt  Attr PSize    PFree
  /dev/vdb   vg_data lvm2 a--  <200.00g 1020.00m

"fdisk" was telling me the disk was already 300G...

[root@VM ~]# fdisk /dev/vdb

Welcome to fdisk (util-linux 2.32.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

The old LVM2_member signature will be removed by a write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0xd46fa2fc.

Command (m for help): p
Disk /dev/vdb: 300 GiB, 322122547200 bytes, 629145600 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xd46fa2fc

I did a pvscan... and nothing. What I was missing? just "pvresize".... and then I can see my extra 100G in the PV and in the VG. So I can create the new LV I wanted...

[root@VM ~]# pvresize /dev/vdb
  Physical volume "/dev/vdb" changed
  1 physical volume(s) resized or updated / 0 physical volume(s) not resized
[root@VM ~]# pvs
  PV         VG      Fmt  Attr PSize    PFree   
  /dev/vdb   vg_data lvm2 a--  <300.00g <101.00g
[root@VM ~]# 
[root@VM ~]# vgs
  VG      #PV #LV #SN Attr   VSize    VFree   
  vg_data   1   1   0 wz--n- <300.00g <101.00g