La variabile non analizza come stringa


10

Problema

Ho cercato di estrarre il livello del segnale per il wifi nel modo seguente, in uno script bash (le virgolette sembrano non fare differenza):

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

Se echo $stringottengo ciò che mi aspetto:

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

Ma se provo a ottenere una sottostringa, echo ${string:5}restituisce la stessa cosa.


debuging:

Se incollo l'output di wconfig wlan0 | grep -I Signaldirettamente nella variabile: string="Link Quality=63/70 Signal level=-47dBm"allora tutto funziona come previsto.

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

Domanda: Secondo Internet, tutte le variabili bash sono memorizzate come stringhe di caratteri. Pertanto, il risultato del debug avrebbe dovuto essere lo stesso del mio problema originale. C'è qualche motivo per cui non viene analizzato come testo nel problema originale?

Risposte:


15

Questo perché echo $stringnon si stampa semplicemente il valore di string; per prima cosa esegue un'operazione split + glob - una delle conseguenze delle quali è eluso lo spazio bianco principale:

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

mentre

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

Possiamo vedere che c'è una sequenza di caratteri di spazi bianchi all'inizio di $string- in effetti ce ne sono più di 5, quindi la rimozione di 5 lascia ancora una stringa con spazi bianchi ${string:5}iniziali, che elimina anche un'espansione di sottostringa non quotata ( ):

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

Per ulteriori discussioni vedere:


4
Tl; dr cita sempre le tue variabili
gronostaj,

6

Questo funziona sulla mia macchina:

$ 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
  • Sostituire wlp60s0con la macchina wlan0.
  • Nota che sta usando Ubuntu 16.04 e Ubuntu 19.04 dove c'è uno spazio tra 42e dBm. Pertanto, il cutcomando è incaricato di stampare i campi n. 4 e n. 5. Nella tua domanda non c'è spazio, quindi non sono sicuro di quale versione stai utilizzando.

Puoi anche usare:

$ echo $string | cut -d'=' -f3
-42 dBm
  • In questo caso cutviene detto di utilizzare =come delimitatore di campo.

Se si desidera utilizzare ${string...}sebbene la sintassi corretta sia:

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

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

Entrambi i metodi funzioneranno per prendere la sottostringa dopo l'ultima =. Il metodo originale di 5nella tua domanda non capisco come possa funzionare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.