Problema estranho passando variáveis do arquivo de texto

0

Eu tenho um script que executa outro script para cada linha em um arquivo.

Quando eu echo each $line eu posso ver o conteúdo completo da linha como esperado.

No entanto, o connect.sh only $1 está definido como user\ name .

Quando eu tento usar "$line" , $1 em connect.sh acaba sendo user\ name user\ password .

Como posso configurar o fluxo do programa para que reboot.sh passe cada linha de /tmp/history para connect.sh como 2 parâmetros.

Com o resultado final, $1 é user\ name e $2 é user\ password ?

reboot.sh:

if [ -e "/tmp/history" ]; then
  while read -r line; do
    echo $line
    connect.sh $line \
      && break
  done </tmp/history
fi

connect.sh:

echo $1
echo $2

/ tmp / history:

user\ name user\ password
    
por Philip Kirkbride 22.11.2017 / 17:47

2 respostas

2

Eu suponho que as barras invertidas estão lá para escapar dos dois espaços para que eles não separem os valores.

Com read -r line , você obtém toda a linha na variável line , de modo que line contenha user\ name user\ password , com os backspaces. Não é fácil dividir isso sem truques com eval . Um $line sem aspas será dividido em espaços em branco, barras invertidas ou não. Citado, ele se expande em uma palavra, como você viu.

Felizmente, read pode lidar com barras invertidas e dividir sua entrada em duas (ou mais) variáveis. Isso teria as variáveis contendo user name e user password (com as barras invertidas removidas):

while read user pass ; do 
    echo "user: $user"
    echo "pass: $pass"
    ./connect.sh "$user" "$pass"
done < file

No entanto, se você quiser permitir espaços em branco no nome de usuário e na senha, talvez seja melhor usar algum outro delimitador do que o espaço. Dois pontos são comuns, então você teria uma entrada assim:

user name:user pass word

E depois leia com

while IFS=: read -r user pass ; do 
    echo "user: $user"
    echo "pass: $pass"
done < file          

(Isso deve funcionar desde que a senha não termine com dois pontos)

    
por 22.11.2017 / 18:54
0

Se você tiver um argumento com espaços, você precisará certificar-se de aspas duplas para evitar que connect.sh o interprete como múltiplos argumentos. Você pode querer dividir a string em vários argumentos. Não sei qual é o formato da linha, mas você pode fazer algo assim:

line="user name user password"
# Split the line into space-separated tokens and store 1 and 2
UNAME=$(echo "$line" | cut -d ' ' -f 1,2)
# Split the line into space-separated tokens and store 3 and 4
UPASSWD=$(echo "$line" | cut -d ' ' -f 3,4)
echo "$UNAME"
echo "$UPASSWD"

Isso deve imprimir:

user name
user password

Você provavelmente precisará fazer alguns ajustes com base no formato real da linha de entrada. Por exemplo, se sua linha $ tiver o nome de usuário e a senha do usuário separados por uma vírgula, você poderá executar:

line="user name,user password"
# Split the line into comma-separated tokens and store 1
UNAME=$(echo "$line" | cut -d ',' -f 1)
# Split the line into comma-separated tokens and store 2
UPASSWD=$(echo "$line" | cut -d ',' -f 2)
echo "$UNAME"
echo "$UPASSWD"

Lembre-se de que, se estiver passando um argumento para um programa e esse argumento tiver espaços, será necessário usar aspas duplas para que o programa o veja como um argumento.

    
por 22.11.2017 / 18:03

Tags