web-dev-qa-db-ja.com

変数は文字列として解析されません

問題

私は次の方法でbashスクリプトでwifiの信号レベルを抽出しようとしました(引用符は違いがないようです)。

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
Ion Sme

これは、echo $stringstringの値を出力するだけではないためです。最初にsplit + glob操作を実行します-その結果の1つは、先頭の空白が省略されることです。

$ 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
steeldriver

これは私のマシンで動作します:

$ 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に置き換えます。
  • これは、42dBmの間にスペースがあるUbuntu 16.04およびUbuntu 19.04を使用しています。そのため、cutコマンドは、フィールド#4および#5を印刷するように指示されます。あなたの質問ではスペースがないので、あなたが使っているバージョンがわかりません。

あなたも使うことができます:

$ echo $string | cut -d'=' -f3
-42 dBm
  • この場合、cut=をフィールド区切り文字として使用するように指示されます。

${string...}を使用する場合、正しい構文は次のとおりです。

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

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

どちらの方法でも、最後の=の後の部分文字列を取得できます。あなたの質問の5の元の方法はどのように機能するのかわかりません。

6