Змінна не розбирає як рядок


10

Проблема

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

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; спочатку виконується операція спліт + глобус - один з наслідків якого полягає у тому, що провідне пробільне поле випромінено:

$ 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

Для додаткової дискусії дивіться:


4
Tl; dr завжди
цитуйте

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вашого запитання я не розумію, як це може працювати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.