Questão script de cinzas: variável que contém espaço se recusa a receber


Estou tentando executar o script listado em http://talk.maemo.org/showthread.php?t=70866&page=2 em seu hardware pretendido, um telefone Nokia Linux executando o BusyBox ash. O script recebe o nome da rede WiFi como um parâmetro e tenta conectar o telefone a ele. Eu suspeito que o script funciona, mas meu SSID, BU (802.1x), tem espaço e parênteses nele. Então, quando eu digito no prompt de comando

autoconnect.sh BU\ \(802.1x\)

Eu recebo vários erros. Primeiro,

LIST=`iwconfig wlan0 | awk -F":" '/ESSID/{print $2}'`
if [ $LIST = "\"$1\"" ]; then

... falha, até eu estou conectado à rede. O erro não é evitado usando aspas simples ou duplas em vez de caracteres de escape no prompt de comando.

Segundo,

if [ -z `iwlist wlan0 scan | grep -m 1 -o \"$1\"` ]; then
    echo SSID \"$1\" not found;

mostra que o grep não encontra a string, embora o mesmo grep, digitado diretamente no prompt de comando, encontre 'BU (802.1x)'.

Como cito US $ 1 nas duas circunstâncias acima, para que funcione com o SSID da minha rede, contendo espaços e parênteses?

Obrigado.


3


origem




Respostas:


A saída de iwconfig coloca o nome do ponto de acesso entre aspas duplas, o que leva a alguma estranheza. O autor do roteiro lida com esse "artefato" em seu roteiro, em vez de se livrar dele imediatamente. Sugiro remover as aspas antes de fazer qualquer outra coisa. Duas abordagens possíveis seriam:

$ eval moo=`iwconfig wlan0 | awk -F":" '/ESSID/{print $2}' `
$ moo=`iwconfig wlan0 | awk -F":" '/ESSID/{print $2}' |tr -d \"`

O primeiro executa a instrução de atribuição de variáveis ​​"literalmente", enquanto o outro remove aspas duplas da string de saída.

O segundo problema com o script reside no pressuposto de que é bom usar $ LIST sem citá-lo (já que a string teria contido aspas duplas). Acho que isso é um erro porque a string ainda é avaliada como dois tokens:

$ moo='"aaa bbb"'
$ if [ $moo = "\"aaa bbb\""];then ok;fi
ash: bbb": unknown operand

$  if [ "$moo" = "\"aaa bbb\"" ];then echo ok;fi
ok

Para corrigir isso, cite os parâmetros entre colchetes e elimine as aspas com escape no segundo argumento (porque as removemos da saída do iwconfig):

if [ "$LIST" = "$1" ]; then ...

Além disso, para passar uma string com caracteres irregulares (espaço, parênteses) como um argumento para um script, basta citar:

$ autoconnect.sh "a name (with a comment)"

A última parte sobre a correspondência do nome com o grep já foi respondida adequadamente por Glenn Jackman.

Nota: O acima foi testado com cinza BusyBox (1.20.2).


2



Obrigado, desejo poder marcar as duas respostas como aceitas. Ambos funcionaram muito bem, ou pelo menos parece que sim. Infelizmente, o script nunca é bem-sucedido, porque a próxima linha é um awk que requer que cada espaço seja escapado. Vai postar como uma questão separada. - Nick Alexander


Não tente adicionar citações literais. Você precisa if [ "$LIST" = "$1" ]; .... Ambas as variáveis ​​precisam ser citadas, de forma que o comando de teste receba exatamente 3 argumentos - isso é especialmente importante porque os valores contêm espaços.

O mesmo conselho para o segundo: if [ -z $(iwlist wlan0 scan | grep -m 1 -o "$1") ]; ...

A melhor maneira de escrever o acima: if iwlist wlan0 scan | grep -q "$1"; ...


1