ตัวแปรไม่แยกวิเคราะห์เป็นสตริง


10

ปัญหา

ฉันพยายามแยกระดับสัญญาณ wifi ในวิธีต่อไปนี้ในสคริปต์ทุบตี (คำพูดดูเหมือนจะไม่แตกต่างกัน):

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

ถ้าฉันecho $stringฉันได้รับสิ่งที่ฉันคาดหวัง:

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

แต่ถ้าฉันลองรับสายอักขระย่อยecho ${string:5}มันจะส่งคืนสิ่งเดียวกัน


debuging:

ถ้าฉันวางผลลัพธ์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

คำถาม:ตามอินเทอร์เน็ตตัวแปรทุบตีทั้งหมดจะถูกเก็บเป็นสตริงอักขระ ดังนั้นผลลัพธ์การดีบักควรเหมือนกันกับปัญหาดั้งเดิมของฉัน มีเหตุผลบางอย่างที่ไม่แยกวิเคราะห์ข้อความในปัญหาดั้งเดิมหรือไม่?

คำตอบ:


15

นี่เป็นเพราะecho $stringไม่เพียงพิมพ์ค่าของstring; ก่อนอื่นให้ดำเนินการแยก + 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 ยังคงใบสตริงด้วยช่องว่างชั้นนำซึ่งการขยายตัวย่อย unquoted (ก${string:5}) นอกจากนี้ยัง elides:

$ 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 จะพูดถึงตัวแปรของคุณเสมอ
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
  • สำหรับเครื่องของคุณแทนที่ด้วยwlp60s0wlan0
  • หมายเหตุนี้ใช้อูบุนตู 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ในคำถามของคุณฉันไม่เข้าใจวิธีการทำงาน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.