Problema estranho ao passar variáveis ​​de arquivo de texto

Problema estranho ao passar variáveis ​​de arquivo de texto

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

Quando echocada um $lineposso ver o conteúdo completo da linha conforme o esperado.

No entanto, inside connect.shonly $1está definido como user\ name.

Quando tento usar "$line", $1acaba connect.shsendo user\ name user\ password.

Como posso configurar o fluxo do programa para que reboot.shpasse cada linha /tmp/historycomo connect.sh2 parâmetros.

Com o resultado final que $1é user\ namee $2é user\ password?

reiniciar.sh:

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

conectar.sh:

echo $1
echo $2

/tmp/histórico:

user\ name user\ password

Responder1

Presumo que as barras invertidas existam para escapar dos dois espaços, para que não separem os valores.

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

Felizmente, readele pode lidar com barras invertidas e dividir sua entrada em duas (ou mais) variáveis. Isso faria com que as variáveis ​​​​contivessem user namee 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 além do espaço. Dois pontos são comuns, então você teria uma entrada como esta:

user name:user pass word

E então 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)

Responder2

Se você tiver um argumento com espaços, certifique-se de colocar aspas duplas na string para evitar connect.shinterpretá-la como vários argumentos. Você pode querer dividir a string em vários argumentos. Não tenho certeza de 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

Provavelmente você 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 vírgula, você pode 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"

Apenas lembre-se de que se você estiver passando um argumento para um programa e esse argumento tiver espaços, você precisará usar aspas duplas para fazer o programa vê-lo como um argumento.

informação relacionada