Variable doesn't parse as string

This is because echo $string doesn't simply print the value of string; it first perform a split+glob operation - one of the consequences of which is that leading whitespace is elided:

$ string=$(iwconfig wls1 | grep Signal)
$ echo $string
Link Quality=38/70 Signal level=-72 dBm

whereas

$ echo "$string"
          Link Quality=38/70  Signal level=-72 dBm  

We can see that there is a sequence of whitespace characters at the start of $string - in fact there are more than 5, so removing 5 still leaves a string with leading whitespace, which an unquoted substring expansion (${string:5}) also elides:

$ echo "${string:5}"
     Link Quality=38/70  Signal level=-72 dBm  
$ echo ${string:5}
Link Quality=38/70 Signal level=-72 dBm

For additional discussion see:

  • When is double-quoting necessary?

  • Why does my shell script choke on whitespace or other special characters?


This works on my machine:

$ string="$(iwconfig wlp60s0 | grep -I Signal)"
$ echo $string
Link Quality=68/70 Signal level=-42 dBm
$ echo $string | cut -d' ' -f4,5
level=-42 dBm
  • For your machine replace wlp60s0 with wlan0.
  • Note this is using Ubuntu 16.04 and Ubuntu 19.04 where there is a space between 42 and dBm. As such the cut command is instructed to print fields #4 and #5. In your question there is no space so I'm not sure what version you are using.

You could also use:

$ echo $string | cut -d'=' -f3
-42 dBm
  • In this case cut is told to use = as field delimiter.

If you want to use ${string...} though the correct syntax is:

$ echo ${string##*=}
-38 dBm

$ echo "${string##*=}"
-38 dBm  

Either method will work to take the substring after the last =. The original method of 5 in your question I don't understand how it can work.