Using expect to migrate multiple repositories - expect

I have multiple repositories , which I want to convert to git from svn.
I try to write a simple expect script that convert one repo.
#!/usr/bin/expect
spawn svn2git svn://svn-server/repo --username $username --verbose
expect {Password for '$username'}
send "$password\r"
He puts password but then exit by timeout.

Git launches SSH internally to connect to a remote repository, and SSH detects when it is launched from another program, and disallows to enter passwords from scripts as a security feature.
You will need a specialized program like sshpass to enter passwords into SSH from scripts, or set up SSH keys.

I presume svn2git takes more than a few seconds to complete. Add this after your send command
set timeout -1
expect eof

Related

automation script for git cmds

i'm trying to write a bash script that will automate some of the operation that we are doing on daily basic:
1. clone different repos
2. checkout some specific commits
3. compile
4. etc.
my challenge is, that I want this script to be used by different users and I don't want the script to prompt for password for each git cmd.
I thought to get the username + pwd as arguments to the script and then
git clone https://username:pasword#gitlab.../repoName/usename/proj.git
but I always get an error of "TCP connection reset by peer".
obviously running ssh command or https command without the username builtin working for me fine
any idea?
If you must use "https" instead "ssh" try with expect script.
#!/usr/bin/expect -f
spawn git pull
expect "Username"
send "put here your username\r"
expect "Password"
send "put here your password\r"
interact
You can use bash and expect in the same script as well.

How to non-interactively feed ssh with Time-based One-Time Password?

Some supercomputers require time-based one-time password (OTP) to login via ssh. I want to avoid typing the password every time and automate login/scp/rsync via bash script, in which I generate the one-time password and then pass the one-time password to ssh by using sshpass:
sshpass -p my_password_and_OTP ssh user#hostname
This sshpass works for usual ssh, but my testing indicates it does not work for ssh requiring one-time password. I am wondering whether there is a way to non-interactively feed ssh with Time-based One-Time Password.
Here is my solution using expect+oathtool:
#!/usr/bin/expect -f
set otp [exec oathtool --totp -b my_secrete_key]
set timeout -1
spawn scp a.f90 usrname#cori.nersc.gov:~/
expect "Password + OTP:"
send -- "my_passwd${otp}\r"
expect eof
I use oathtool to generate the one-time-password and store the result in a variable otp.

expect script unable to fetch server logs into the text file

I am trying to access remote ssh server from a unix client machine. For this i have used expect script which is calling a bash script to fetch some lines from server log file.
Below is my code:
#!/usr/local/bin/expect -f
set pass "password"
set prompt "(%|$|#)"
spawn ssh deployed#172.16.166.111
expect "password:"
send "$pass\r"
expect -re $prompt
send -- "./access_srvr_log.sh\r"
send -- "exit\r"
code for access_srvr_log.sh file:
#!/usr/local/bin/expect
dir="/home/deployer/Desktop/McKinsey-McKinsey-AdminPanel/log"
tail -n 100 $dir/development.log
echo "hello"
echo >> log.txt
i get this error :
./access_srvr_log.sh
-bash: ./access_srvr_log.sh: No such file or directory
Please help. I have tried lot many changes on the above code and finally reached here.
Thanks.
Friends don't let friends use SSH passwords. It's much less secure.
Use ssh-copy-id to copy your public key to the remote server. (It puts the client ~/.ssh/id_rsa.pub into the server .ssh/authorized_keys) Now you can run "ssh deployer#172.16.144.111 ./access_srvr_log.sh", and it won't prompt for a password. That means you no longer need expect and all the odd problems that come with it.
In fact, it's highly recommended that you disable SSH passwords all together.
To make your script even simpler (maintenance-wise) do this:
1) run ssh-keygen -f ~/.ssh/scriptkey on your client (don't enter a password).
2) Put the public part of your key (~/.ssh/scriptkey.pub on the client) into .ssh/authorized_keys on the server. But this time, put command="/home/deployer/access_srvr_log.sh" just before your new key. This tells the server to run that command for that key.
3) Now your script doesn't even need to specify the command, just the private key. (i.e. scp -i ~/.ssh/scriptkey deployer#172.16.144.111 will run the script). This allows the server to change (i.e. move the script, change the script name) without changing the client. It also means someone stealing your (non-password-protected) key can't log in to the server, but only run your log script.
And there are no guessable passwords laying around in scripts. (You are checking your scripts into version control, right?)
You can simplify it down too
#!/bin/bash
{
/usr/bin/expect <<- EOF
spawn ssh deployer#172.16.144.111 "tail -n 100 /home/deployer/Desktop/McKinsey-McKinsey-AdminPanel/log/development.log"
expect "password:"
send "deployer\r"
expect eof
EOF
} |grep -v "deployer#172.16.144.111's password:">> log.txt

Bash Script to SSH into a machine without prompting password and without using keys

I realize this question has been asked a few times but I could not find a relevant answer anywhere in my searching.
I am working in a development environment where security is not an issue and anyone could just guess the password if the thought for a few seconds.
What I am trying to do is simple. I have created an alias function in my local .bashrc file and I would like this function to automatically log into a machine with a default password.
My current implementation looks something like this:
function s () {
ssh root#192.168.1.$1
}
When I run it I get something like this:
~]s 122
ssh root#192.168.1.122
root#192.168.1.122's password:
Using Bash, and not using RSA keys I would like to get this to use the default password 'password'.
I've tried the following where IP and User have already been set.
Do=$(expect -c "
spawn ssh $User#${IP[0]}.${IP[1]}.${IP[2]}.${IP[3]}
expect \"yes/no\"
send \"yes\r\"
expect \"assword\" send \"password\"")
echo $Do
$Do
It gives the follwing error:
Connecting and logging into server using expect
usage: send [args] string
while executing
"send"
invoked from within
"expect "assword" send "password""
Administrator#192.168.1.176's password:
bash: spawn: command not found...
Using the following command I am able to connect a machine. If I remove the interact it just runs the uptime command and closes the connection. With the interact command I am unable to see what I am typing or actually interact with the machine. Any ideas?
Do=$(expect -c "spawn ssh $User#${IP[0]}.${IP[1]}.${IP[2]}.${IP[3]}; set timeout 4; expect \"assword\"; send \"password\n\"; expect \"test\"; send \"uptime\n\"; interact;");echo $Do;
You can do this with the expect tool: http://expect.sourceforge.net/
It's widely available, so depending on your system, the equivalent of sudo apt-get install expect or yum install expect will install it.
Here's an example of an expect script with ssh. This logs you in and gives you control of the interactive prompt:
#!/usr/bin/expect
set login "root"
set addr "127.0.0.1"
set pw "password"
spawn ssh $login#$addr
expect "$login#$addr\'s password:"
send "$pw\r"
expect "#"
send "cd /developer\r"
interact
Here's an example of how to use expect as part of a bash script. This logs in with ssh, cd to /var, runs a script, then exits the ssh session.
#!/bin/bash
...
login_via_ssh_and_do_stuff() {
# build the expect script in bash
expect_sh=$(expect -c "
spawn ssh root#127.0.0.1
expect \"password:\"
send \"password\r\"
expect \"#\"
send \"cd /var\r\"
expect \"#\"
send \"chmod +x my_script.sh\r\"
expect \"#\"
send \"./my_script.sh\r\"
expect \"#\"
send \"exit\r\"
")
# run the expect script
echo "$expect_sh"
}
You can leave these snippets in a script on your local system, and then just alias to the scripts.
Also: I know you said security isn't an issue, but I'd like to just note, again, that the "proper" way to ssh without using a password is to use a ssh key-pair =)
Use sshpass which is available in package repositories on major Linux-es.
For example, when password is in password.txt file:
sshpass -fpassword.txt ssh username#hostname
sshpass runs ssh in a dedicated tty, fooling it into thinking it is
getting the password from an interactive user.

Delete a file on a remote machine using bash script

I want to basically copy files from remote machines, and after copying, delete them.
I have managed to copy the files using expect and scp.
Also, managed to delete the files outside of the script, but not able to use the ssh command inside the script.
This is what I have
#!/usr/bin/expect -f
log_user 1
set timeout -1
set pass "pass"
spawn scp user#remote.machine.com:Desktop/LoginCheck/Login/* .
expect {
password: {send "$pass\r" ; exp_continue}
}
ssh user#remote.machine.com 'rm -rf Desktop/LoginCheck/Login/*'
expect {
password: {send "$pass\r" ; exp_continue}
}
So the scp section of code works.
But the ssh and rm -rf
this is the error for ssh
invalid command name "ssh"
while executing
Can someone provide a working script?
Shouldn't the ssh command be a new spawn? By the way, just reading the wikipedia article on expect, one of the "cons" listed is:
A less obvious argument against Expect is that it can enable
sub-optimal solutions. For example, a systems administrator needing to
log into multiple servers for automated changes might use Expect with
stored passwords, rather than the better solution of ssh agent keys.
The ability to automate interactive tools is attractive, but there are
frequently other options that can accomplish the same tasks in a more
robust manner.
Sounds like you're doing exactly the example sub-optimal solution. If you were using a proper ssh key pair, you wouldn't need expect at all.
Replace ssh with spawn ssh - ssh is not a built-in command of expect.
You just missed the spawn in front of the ssh line:
spawn ssh user#remote.machine.com 'rm -rf Desktop/LoginCheck/Login/*'
You should also add a wait line before it, potentially checking for the exit code of scp.
In any case, don't use expect to automate ssh, use ssh keys and sh scripts like the other posters described.

Resources