Tengo un script esperado que se conecta a un sitio SFTP y carga algunos archivos. El ID y la contraseña están contenidos en archivos de texto locales. El script expect lee esos archivos como una variable y luego los pasa al servidor SFTP.
El problema que estoy experimentando es que se nos proporcionan contraseñas con una complejidad que incluye caracteres especiales ($\,!), etc. Por ejemplo, si la contraseña es contraseña, el $ pasa como especial en lugar de literal. Ya que esto se está pasando a través de una variable (múltiples sitios e ID)
No puedo usar '$pw' ya que literalmente pasará $pw al servidor y usar "$pw" envía caracteres especiales. Lo necesito para pasar la contraseña exactamente como está.
Los he estado escapando a mano hasta ahora (por ejemplo, contraseña) pero eso es tedioso y me gustaría hacerlo de forma automática.
El guión se ve así (nombres y lugares cambiados para proteger a los inocentes)
#!/bin/bash
home=/data/ftp/vf/drop/
un=`cat /home/vf/workflow/.udf/.u/.u$1`
pw=`cat /home/vf/workflow/.udf/.p/.p$1`
sl=`cd /home/vf/workflow/scheduler; grep $1 upload*|cut -d \: -f1`
/usr/bin/expect -c "
spawn /usr/bin/sftp -o KexDHMin=1024 [email protected]$sl.mysteriouslocation.com
set timeout -1
expect *Authentication
expect Password*
send \"$pw\r\"
expect sftp*
send \"mput /$home/$1/transfer/*\r\"
expect sftp*
send \"ls \r\"
expect sftp*
send \"bye\r\"
expect eof
exit
¿Cómo puedo pasar la contraseña al script expect para que envíe los caracteres literales y no les dé un significado especial?
No creo que pueda escribir una "corrección" para el archivo de contraseña en sí, es decir y cada vez que vea un carácter especial, escápelo a través de sed u otros medios, ya que el carácter de escape en sí mismo es especial y podría terminar en un bucle.
¡Su ayuda es muy apreciada!
Respuesta aceptada:
Se puede usar un pequeño fragmento de Perl para escapar (barra invertida) de todos los caracteres ASCII que no coincidan con /[A-Za-z_0-9]/
mediante el uso de la función quotemeta. La línea de comandos de Perl se incorpora fácilmente a su script de shell:
#/bin/sh
pstr='$x%y!zpass' # plain, un-escaped string
estr=$(perl -e 'print quotemeta shift(@ARGV)' "${pstr}")
echo ${estr} # show escaped string
produce:
\$x\%y\!zpass