Eu tenho um script que executa outro script para cada linha de um arquivo.
Quando echo
cada um $line
posso ver o conteúdo completo da linha conforme o esperado.
No entanto, inside connect.sh
only $1
está definido como user\ name
.
Quando tento usar "$line"
, $1
acaba connect.sh
sendo user\ name user\ password
.
Como posso configurar o fluxo do programa para que reboot.sh
passe cada linha /tmp/history
como connect.sh
2 parâmetros.
Com o resultado final que $1
é user\ name
e $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 line
você obtém a linha inteira na variável line
, de modo que line
contém user\ name user\ password
, com os retrocessos. Não é fácil dividir isso sem truques com eval
. Um não citado $line
será dividido em espaços em branco, barras invertidas ou não. Citado, ele se expande em uma palavra, como você viu.
Felizmente, read
ele pode lidar com barras invertidas e dividir sua entrada em duas (ou mais) variáveis. Isso faria com que as variáveis contivessem 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 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.sh
interpretá-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.