Переменная не разбирается как строка

10

проблема

Я попытался извлечь уровень сигнала для Wi-Fi следующим образом, в сценарии bash (кавычки, кажется, не имеют значения):

string="$(iwconfig wlan0 | grep -I Signal)"

Если я echo $string, я получаю то, что ожидаю:

Link Quality=63/70 Signal level=-47dBm

Но если я пытаюсь получить подстроку echo ${string:5}, она возвращает то же самое.


отладки:

Если я вставлю вывод wconfig wlan0 | grep -I Signalнепосредственно в переменную: string="Link Quality=63/70 Signal level=-47dBm"тогда все будет работать как положено.

echo $string 
# Link Quality=63/70 Signal level=-47dBm
echo ${string:5}
# Quality=63/70 Signal level=-47dBm

Вопрос: Согласно Интернету, все переменные bash хранятся в виде символьных строк. Таким образом, результат отладки должен был быть таким же, как моя первоначальная проблема. Есть ли какая-то причина, по которой он не анализируется как текст в исходной задаче?

Ион См
источник

Ответы:

15

Это потому, echo $stringчто не просто печатать значение string; сначала он выполняет операцию split + glob, одно из последствий которой заключается в том, что ведущий пробел исключается:

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

в то время как

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

Мы видим, что в начале есть последовательность пробельных символов $string- на самом деле их больше 5, поэтому удаление 5 все еще оставляет строку с ${string:5}начальным пробелом, которую также исключает расширение без кавычек подстроки ( ):

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

Для дополнительного обсуждения см .:

steeldriver
источник
4
Tl; dr всегда цитирую ваши переменные
gronostaj
6

Это работает на моей машине:

$ 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
  • Для вашей машины замените wlp60s0на wlan0.
  • Обратите внимание, что это использует Ubuntu 16.04 и Ubuntu 19.04, где между 42и dBm. Как таковая cutкоманда получает команду на печать полей № 4 и № 5. В вашем вопросе нет места, поэтому я не уверен, какую версию вы используете.

Вы также можете использовать:

$ echo $string | cut -d'=' -f3
-42 dBm
  • В этом случае cutрекомендуется использовать в =качестве разделителя полей.

Если вы хотите использовать, ${string...}хотя правильный синтаксис:

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

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

Любой метод будет работать, чтобы взять подстроку после последней =. Оригинальный метод 5в вашем вопросе я не понимаю, как это может работать.

WinEunuuchs2Unix
источник