J'ai un script expect qui se connecte à un site SFTP et télécharge certains fichiers. L'ID et le mot de passe sont contenus dans des fichiers texte locaux. Le script expect lit ces fichiers en tant que variable, puis les transmet au serveur SFTP.
Le problème que je rencontre est que nous recevons des mots de passe complexes qui incluent des caractères spéciaux ($\,!), etc. Par exemple, si le mot de passe est mot de passe $, le $ passe comme un spécial plutôt que comme un littéral. Cela passe par une variable (plusieurs sites et identifiants)
Je ne peux pas utiliser '$pw' car il transmettra littéralement $pw au serveur et l'utilisation de "$pw" enverra des caractères spéciaux. J'en ai besoin pour transmettre le mot de passe exactement tel quel.
Je les ai échappés à la main jusqu'à présent (par exemple, mot de passe \ $) mais c'est fastidieux et j'aimerais le faire par script.
Le script ressemble à ceci (noms et lieux changés pour protéger les innocents)
#!/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
Comment puis-je transmettre le mot de passe au script expect afin qu'il envoie les caractères littéraux et ne leur donne pas de signification particulière ?
Je ne pense pas pouvoir scripter un "correctif" pour le fichier de mot de passe lui-même, ce qui signifie entrer et chaque fois qu'il voit un caractère spécial, échappez-le via sed ou d'autres moyens car le caractère d'échappement lui-même est spécial et pourrait se retrouver dans une boucle.
Votre aide est grandement appréciée !
Réponse acceptée :
Un petit extrait Perl peut être utilisé pour échapper (barre oblique inverse) tous les caractères ASCII ne correspondant pas à /[A-Za-z_0-9]/
en utilisant la fonction quotemeta. La ligne de commande Perl s'intègre facilement dans votre script shell :
#/bin/sh
pstr='$x%y!zpass' # plain, un-escaped string
estr=$(perl -e 'print quotemeta shift(@ARGV)' "${pstr}")
echo ${estr} # show escaped string
produit :
\$x\%y\!zpass