Tengo un script que ejecuta otro script para cada línea de un archivo.
Cuando hago echo
cada uno $line
puedo ver el contenido completo de la línea como se esperaba.
connect.sh
Sin embargo, solo el interior $1
está configurado como user\ name
.
Cuando intento usarlo "$line"
, $1
termina connect.sh
siendo user\ name user\ password
.
¿Cómo puedo configurar el flujo del programa para que reboot.sh
pase cada línea /tmp/history
como connect.sh
2 parámetros?
¿Con el resultado final que $1
es user\ name
y $2
es 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/historia:
user\ name user\ password
Respuesta1
Supongo que las barras invertidas están ahí para escapar de los dos espacios y no separar los valores.
Con read -r line
obtienes toda la línea en la variable line
, de modo que line
contiene user\ name user\ password
, con los retrocesos. No es fácil dividir eso sin trucos eval
. Un texto sin comillas $line
se dividirá en espacios en blanco, con barras invertidas o no. Citado, se expande en una palabra, como viste.
Afortunadamente, read
puede manejar barras invertidas y dividir su entrada en dos (o más) variables. Esto haría que las variables contuvieran user name
y user password
(sin las barras invertidas):
while read user pass ; do
echo "user: $user"
echo "pass: $pass"
./connect.sh "$user" "$pass"
done < file
Sin embargo, si desea permitir espacios en blanco en el nombre de usuario y la contraseña, podría ser mejor utilizar algún otro delimitador que no sea el espacio. Los dos puntos son comunes, por lo que tendrías una entrada como esta:
user name:user pass word
Y luego léelo con
while IFS=: read -r user pass ; do
echo "user: $user"
echo "pass: $pass"
done < file
(Eso debería funcionar siempre y cuando la contraseña no termine con dos puntos)
Respuesta2
Si tiene un argumento con espacios, deberá asegurarse de poner comillas dobles en la cadena para evitar connect.sh
que se interprete como argumentos múltiples. Es posible que desees dividir la cadena en varios argumentos. No estoy seguro de cuál es el formato de la línea, pero es posible que puedas hacer algo como esto:
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"
Esto debería imprimir:
user name
user password
Probablemente necesitarás realizar algunos ajustes según el formato real de la línea de entrada. Por ejemplo, si su línea $ tiene el nombre de usuario y la contraseña de usuario separados por una coma, podría ejecutar:
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"
Sólo recuerda que si estás pasando un argumento a un programa y ese argumento tiene espacios, necesitarás usar comillas dobles para que el programa lo vea como un solo argumento.