Biến không phân tích cú pháp dưới dạng chuỗi


10

Vấn đề

Tôi đã cố gắng trích xuất mức tín hiệu cho wifi theo cách sau, trong một tập lệnh bash (trích dẫn dường như không có sự khác biệt):

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

Nếu tôi echo $string, tôi nhận được những gì tôi mong đợi:

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

Nhưng nếu tôi cố gắng để có được một chuỗi con echo ${string:5}, nó sẽ trả về điều tương tự.


Gỡ lỗi:

Nếu tôi dán đầu ra wconfig wlan0 | grep -I Signaltrực tiếp vào biến: string="Link Quality=63/70 Signal level=-47dBm"thì mọi thứ sẽ hoạt động như mong đợi.

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

Câu hỏi: Theo internet, tất cả các biến bash được lưu dưới dạng chuỗi ký tự. Do đó, kết quả gỡ lỗi nên giống như vấn đề ban đầu của tôi. Có một số lý do nó không được phân tích cú pháp như văn bản trong vấn đề ban đầu?

Câu trả lời:


15

Điều này là do echo $stringkhông chỉ đơn giản là in giá trị của string; đầu tiên nó thực hiện thao tác chia + toàn cầu - một trong những hậu quả của việc khoảng trắng hàng đầu bị xóa bỏ:

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

trong khi

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

Chúng ta có thể thấy rằng có một chuỗi các ký tự khoảng trắng khi bắt đầu $string- trên thực tế có hơn 5, do đó, việc xóa 5 vẫn để lại một chuỗi có khoảng trắng hàng đầu, mà một phần mở rộng chuỗi con không được trích dẫn ( ${string:5}) cũng xuất hiện:

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

Để thảo luận thêm, xem:


4
Tl; dr luôn trích dẫn các biến của bạn
gronostaj

6

Điều này hoạt động trên máy của tôi:

$ 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
  • Cho máy của bạn thay thế wlp60s0bằng wlan0.
  • Lưu ý điều này là sử dụng Ubuntu 16.04 và Ubuntu 19.04 có khoảng cách giữa 42dBm. Vì vậy, cutlệnh được hướng dẫn để in các trường # 4 và # 5. Trong câu hỏi của bạn không có chỗ trống nên tôi không chắc bạn đang sử dụng phiên bản nào.

Bạn cũng có thể sử dụng:

$ echo $string | cut -d'=' -f3
-42 dBm
  • Trong trường hợp cutnày được cho là sử dụng =như dấu phân cách trường.

Nếu bạn muốn sử dụng ${string...}mặc dù cú pháp đúng là:

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

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

Một trong hai phương thức sẽ hoạt động để lấy chuỗi con sau lần cuối cùng =. Phương pháp ban đầu 5trong câu hỏi của bạn Tôi không hiểu làm thế nào nó có thể hoạt động.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.