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

Задача

Я попытался извлечь уровень сигнала для 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 хранятся в виде символьных строк. Таким образом, результат отладки должен был быть таким же, как моя первоначальная проблема. Есть ли какая-то причина, по которой он не анализируется как текст в исходной задаче?

10
задан 5 August 2019 в 20:24

2 ответа

Это вызвано тем, что 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

Поскольку дополнительное обсуждение видит:

15
ответ дан 23 November 2019 в 04:21

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

$ 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 в Вашем вопросе я не понимаю, как он может работать.

6
ответ дан 23 November 2019 в 04:21

Другие вопросы по тегам:

Похожие вопросы: