Linux expect script - expect

I've spent the better part of 8 hours trying to figure this out with google, so I hope this warrants asking here.
I need a script that will auto-enter a password when I try to connect from my lubuntu image in vmware to a physical device connected by usb.
I've tried at least 50 different scripts I've found online, but none of them worked (or even recognised spawn as a command)
This is my script:
#!/usr/expect
spawn CPY2T_old.sh
expect "root#10.9.8.2's password:"
send "ThePassword"
expect eof
The contents of CPY2T_old.sh is
#!/bin/bash
cd hellolinux/src/Exercise$1
scp $2 root#10.9.8.2:
The above bash script works fine, but I have to enter the password, which is what I'm trying to avoid in the first place. The expect script gives the following when I execute in cmd:
spawn: command not found
couldn't read file "root#10.9.8.2's password:": no such file or directory
The program 'send' can be found in the following packages:
* mailutils-mh
* nmh
Try: sudo apt-get install <selected package>
couldn't read file "eof": no such file or directory
I've downloaded mailutils and nmh at least a dozen times by now as well. Elsewhere I read I need to #echo off at the top, but this command isn't recognised and gives an error.
EDIT: I can't do passwordless ssh to this device, so please don't suggest it.

I see 2 errors: first
#!/usr/expect
You want
#!/usr/bin/expect
That should have caused an error: how are you launching your expect script?
Second
send "ThePassword"
You forgot to hit enter
send "ThePassword\r"

#!/usr/bin/expect
set timeout 60
spawn ssh user#ip
expect "user#ip's password: "
send "Password\r"
interact
Note:Please be sure of all scripts are executable with command $ chmod +x #file_name or $ chmod 700 #file_name.
\r to execute
Github link:https://github.com/asarari207/Lunix_sh

Related

Server asking terminal type prevents me from auto-running commands

I wish to ssh into a server in my department, cd to a directory automatically, and hopefully be able to auto-run other commands if I want. I have tried several ways that have worked for lots of people on stack-overflow, but they did not work for me.
I have tried the methods from the following threads:
Can I ssh somewhere, run some commands, and then leave myself a prompt?
Run ssh and immediately execute command
In particular, I have tried:
1. ssh one-liner
ssh -t user#domain.com 'cd /some/path; bash -l'
and
2. using the expect script
#!/usr/bin/expect -f
spawn ssh $argv
send "cd /some/path\n"
interact
Both codes look fine, and have worked for people in the threads. However, they did not work for me.
The problem, I expect, lies in the fact that the department server asks me automatically about my terminal type as I login, preventing my auto-commands to be run properly.
$ ssh -t user#domain.com 'cd /some/path; bash -l'
Terminal type? [xterm-256color]
After hitting , it takes me into the home directory as if I haven't cd yet.
The second way gives a similar result.
How can I get over this? Thank you very much in advance!

How to return to the script once sudo is done

I am on a server and running a script file that has following code.
ssh username#servername
sudo su - root
cd /abc/xyz
mkdir asdfg
I am able to ssh... but then the next command is not working.. the script is not sudo-ing. any idea?
Edit: Able to create a mech id and then do the things.. though still looking for the answer to above question :|
First of all your command will "stuck" on the first line because it will go into an interactive mode. The ssh command will require a password to be provided by a user (unless there is an sshkey being used) . And if the ssh is logged into the remote server then it will wait for user commands from standard input.
Secondly the lines following the ssh command will be executed only when the first process has exited. This is why your script is not "sudoing" - it's waiting for the ssh to end.
So if your point is to run a command on a remote server then put the command as a parameter into the same line as ssh connection. In your case:
ssh user#server sudo su - root
But this will not be of satisfaction for you. I suggest you create a script of what you want to execute on the remote server and then execute the script.
ssh user#server scriptName
The sudo thing here is very tricky because again your script might get stuck in the interactive mode waiting for a password to be inserted so I suggest you think again on the basis of the script.
mb47!
You want to run the script on the remote computer, correct?
On the remote machine, create a file containing the commands you would like to execute.
Then, on the other machine, run ssh user#machine /path/to/script/you/created/earlier
I hope this helps!
ALinuxLover

Spawn command not found

I have an error trying to run a .sh file
line 2: spawn: command not found
": no such file or directory
bash.sh: line 3: expect: command not found
bash.sh: line 4: send: command not found
#!/usr/bin/expect -f
spawn sftp -o IdentityFile=MyFile.ppk 500200243#XXX.XXX.XXX.XXX
expect "XXX.XXX.XXX.XXX.gatewayEnter passphrase for key 'MyFile.ppk.ppk':"
send "myPassword"
Any idea why it happens?
that is an expect script, so ".exp" would be an appropriate file extension: mv bash.sh sftp.exp
do not launch it like bash bash.sh or sh bash.sh. Do this:
make the program executable: chmod a+x sftp.exp
launch it with ./sftp.exp or /path/to/sftp.exp or move it to a directory in your $PATH and launch it just with sftp.exp
after you send "myPassword" you have to "hit enter": send "myPassword\r"
while developing an expect program, add exp_internal 1 to the top.
Good luck, and come back with further questions.
It works OK for me (error from sftp: ssh: Could not resolve hostname XXX.XXX.XXX.XXX: Name or service not known), though the .sh extension for an expect (tcl) script is a little off-putting ;-)
Often when this sort of unexplainable/unpredictable behavior happens, it is because the script was edited under windows (notepad.exe), which uses \r\n to delimit lines. This plays havoc with unix/linux scripts, as only \n is expected as a line delimiter.
You can use the dos2unix and unix2dos utilities to convert between the two formats. As an experiment, I converted your script to "dos" format, and sure enough got a similar error:
ubuntu#ubuntu:~$ unix2dos bash.sh
unix2dos: converting file bash.sh to DOS format ...
ubuntu#ubuntu:~$ ./bash.sh
": no such file or directory
ubuntu#ubuntu:~$ dos2unix bash.sh
dos2unix: converting file bash.sh to Unix format ...
ubuntu#ubuntu:~$ ./bash.sh
spawn sftp -o IdentityFile=MyFile.ppk 500200243#XXX.XXX.XXX.XXX
ssh: Could not resolve hostname XXX.XXX.XXX.XXX: Name or service not known
Couldn't read packet: Connection reset by peer
send: spawn id exp6 not open
while executing
"send "myPassword""
(file "./bash.sh" line 4)
ubuntu#ubuntu:~$
It seems /usr/bin/expect haven't been installed in your machine. So you will get 'command not found'
Use which expect to check, and install it to correct path.
I was also getting the same error. it got resolved by using expect in following way:
DIRNAME=$(date +%F:%T)
expect_sh=$(expect -c "
spawn scp -r ABC xxx#yyy.yy.yy.yyy:/root/$DIRNAME
expect \"password:\"
send \"xxxx\r\"
expect \"#\"
spawn ssh -o StrictHostKeychecking=no xxx#yyy.yy.yy.yyy
expect \"password:\"<
send \"xxxx\r\"
expect \"#\"
send \"rm -f /root/$DIRNAME/abc.txt\r\"
expect \"#\"
send \"scp -r /root/$DIRNAME/* root#zzz.zz.zz.zzz:/root/ABC/\r\"
expect \"password:\"
send \"xxxxx\r\"
expect \"#\"
send \"exit \r\"
")<b
echo "$expect_sh"
It all depends on how you invoke the command. Like ray said, even if you specify the environment with a bang at the top, you still have to run it using expect -f.

Shell script to automate SonicWall firewall SSH session not working

I'm trying to write a shell script (Bash) to log into a SonicWall firewall device and issue a command to perform automated backups of the devices ruleset. I prefer to do this in Bash but I will accept a python, perl, except, or applescript solution. If it cannot be done in bash please mention that.
Problems:
1.) SSH server on firewall is custom, a user name and password has to be specified after issuing a
$ ssh server.com
so no matter what username you issue e.g.
$ ssh admin#server.com
the SSH server still presents a username and password box after
2.) The SSH server is minimal and I cannot use public-keys
I tried using a here-document but it isn't working and it results in an immediate "connection closed by remote host".
The command I need to execute takes the form of this:
export preferences ftp "ftp.server.com" "user1" "mypassword" "output.exp"
Connecting gives me this:
$ ssh admin#server.com
Copyright (c) 2010 SonicWALL, Inc.
User:
After a username is issued it brings up the password prompt:
User:user1
Password:
I tried a here-document to no avail.
$ ssh server <<+
user1
mypassword
export preferences ftp "ftp.server.com" "user1" "mypassword" "output.exp"
exit
+
Pseudo-terminal will not be allocated because stdin is not a terminal.
Connection to 10.1.1.1 closed by remote host.
I tried using echo to pipe in commands too but that doesn't work either.
Typing the commands in manually works just fine.
Any help on this would be greatly appreciated.
As others have suggested, expect is probably what you want to use here.
Here's a short example of how to work with it from bash to get you started:
login=root
IP=127.0.01
password=helloworld
# +whatever variables you need to use
# Run the expect script from bash
expect_sh=$(expect -c "
spawn ssh $login#$IP
expect \"password:\"
send \"$password\r\"
expect \"#\"
send \"cd $dest_dir\r\"
expect \"#\"
send \"chmod +x $server_side_script $other_script\r\"
expect \"#\"
send \"./$device_side_script\r\"
expect \"#\"
send \"cat results_file\r\"
expect \"#\"
send \"exit\r\"
")
# Output or do something with the results
echo "$expect_sh"
You can automate the ssh session using the original expect, here is a nice article discussing it in detail: http://solar1.net/drupal/automating%20SSH%20with%20expect or the Python module pexepect: http://linux.byexamples.com/archives/346/python-how-to-access-ssh-with-pexpect/
I'm not a BASH expert but i had to do something where interactive password prompts was causing me a problem.
Basically your script needs to wait to be asked to enter login credentials, and pass them when prompted in order to login, once logged in you can issue the command.
I recommend looking at spawning "expect" sessions. Basically in your script you use expect to basically say "i expect to see password: in the response, when i do, i need to pass in the following data".
Here's the wiki page which helps explain it http://en.wikipedia.org/wiki/Expect
and if you google around you will find lots of help.
that didn't work for me.
I had to pass the variables to the script at launch.
Example launch script login2.sh, with three arguments:
-bash-4.1$ ./login2.sh Jan2**** HIE_SUPER 10.244.112.182

How to run the sftp command with a password from Bash script?

I need to transfer a log file to a remote host using sftp from a Linux host. I have been provided credentials for the same from my operations group. However, since I don't have control over other host, I cannot generate and share RSA keys with the other host.
So is there a way to run the sftp command (with the username/password provided) from inside the Bash script through a cron job?
I found a similar Stack Overflow question, Specify password to sftp in a Bash script, but there was no satisfactory answer to my problem.
You have a few options other than using public key authentication:
Use keychain
Use sshpass (less secured but probably that meets your requirement)
Use expect (least secured and more coding needed)
If you decide to give sshpass a chance here is a working script snippet to do so:
export SSHPASS=your-password-here
sshpass -e sftp -oBatchMode=no -b - sftp-user#remote-host << !
cd incoming
put your-log-file.log
bye
!
Another way would be to use lftp:
lftp sftp://user:password#host -e "put local-file.name; bye"
The disadvantage of this method is that other users on the computer can read the password from tools like ps and that the password can become part of your shell history.
A more secure alternative which is available since LFTP 4.5.0 is setting the LFTP_PASSWORD environment variable and executing lftp with --env-password. Here's a full example:
export LFTP_PASSWORD="just_an_example"
lftp --env-password sftp://user#host -e "put local-file.name; bye"
# Destroy password after use
export LFTP_PASSWORD=""
LFTP also includes a cool mirroring feature (can include delete after confirmed transfer --Remove-source-files):
lftp -e 'mirror -R /local/log/path/ /remote/path/' --env-password -u user sftp.foo.com
EXPECT is a great program to use.
On Ubuntu install it with:
sudo apt-get install expect
On a CentOS Machine install it with:
yum install expect
Lets say you want to make a connection to a sftp server and then upload a local file from your local machine to the remote sftp server
#!/usr/bin/expect
spawn sftp username#hostname.com
expect "password:"
send "yourpasswordhere\n"
expect "sftp>"
send "cd logdirectory\n"
expect "sftp>"
send "put /var/log/file.log\n"
expect "sftp>"
send "exit\n"
interact
This opens a sftp connection with your password to the server.
Then it goes to the directory where you want to upload your file, in this case "logdirectory"
This uploads a log file from the local directory found at /var/log/ with the files name being file.log to the "logdirectory" on the remote server
You can use lftp interactively in a shell script so the password not saved in .bash_history or similar by doing the following:
vi test_script.sh
Add the following to your file:
#!/bin/sh
HOST=<yourhostname>
USER=<someusername>
PASSWD=<yourpasswd>
cd <base directory for your put file>
lftp<<END_SCRIPT
open sftp://$HOST
user $USER $PASSWD
put local-file.name
bye
END_SCRIPT
And write/quit the vi editor after you edit the host, user, pass, and directory for your put file typing :wq .Then make your script executable chmod +x test_script.sh and execute it ./test_script.sh.
I was recently asked to switch over from ftp to sftp, in order to secure the file transmission between servers. We are using Tectia SSH package, which has an option --password to pass the password on the command line.
example : sftp --password="password" "userid"#"servername"
Batch example :
(
echo "
ascii
cd pub
lcd dir_name
put filename
close
quit
"
) | sftp --password="password" "userid"#"servername"
I thought I should share this information, since I was looking at various websites, before running the help command (sftp -h), and was i surprised to see the password option.
You can override by enabling Password less authentication. But you should install keys (pub, priv) before going for that.
Execute the following commands at local server.
Local $> ssh-keygen -t rsa
Press ENTER for all options prompted. No values need to be typed.
Local $> cd .ssh
Local $> scp .ssh/id_rsa.pub user#targetmachine:
Prompts for pwd$> ENTERPASSWORD
Connect to remote server using the following command
Local $> ssh user#targetmachine
Prompts for pwd$> ENTERPASSWORD
Execute the following commands at remote server
Remote $> mkdir .ssh
Remote $> chmod 700 .ssh
Remote $> cat id_rsa.pub >> .ssh/authorized_keys
Remote $> chmod 600 .ssh/authorized_keys
Remote $> exit
Execute the following command at local server to test password-less authentication.
It should be connected without password.
$> ssh user#targetmachine
The easiest way I found to accomplish this, without installing any third-party library like Expect, SSHPASS...etc, is by using a combination of CURL, and SFTP. Those two are almost in every Linux machine.
This is the command you should execute, after changing the values.
curl -k "sftp://SERVER_IP:SERVER_PORT/FULL_PATH_OF_THE_FILE" --user "SERVER_USER:SERVER_PASSOWRD" -o "THE_NAME_OF_THE_FILE_AFTER_DOWNLOADING_IT"
Example:
curl -k "sftp://10.10.10.10:77/home/admin/test.txt" --user "admin:123456" -o "test.txt"
Explanation:
We are connecting to the server 10.10.10.10:77 using the username admin and password 123456, to move the file /home/admin/test.txt from that server to the server you are using currently to execute the above command.
Combine sshpass with a locked-down credentials file and, in practice, it's as secure as anything - if you've got root on the box to read the credentials file, all bets are off anyway.
Bash program to wait for sftp to ask for a password then send it along:
#!/bin/bash
expect -c "
spawn sftp username#your_host
expect \"Password\"
send \"your_password_here\r\"
interact "
You may need to install expect, change the wording of 'Password' to lowercase 'p' to match what your prompt receives. The problems here is that it exposes your password in plain text in the file as well as in the command history. Which nearly defeats the purpose of having a password in the first place.
You can use sshpass for it. Below are the steps
Install sshpass For Ubuntu - sudo apt-get install sshpass
Add the Remote IP to your known-host file if it is first time
For Ubuntu -> ssh user#IP -> enter 'yes'
give a combined command of scp and sshpass for it.
Below is a sample code for war coping to remote tomcat
sshpass -p '#Password_For_remote_machine' scp /home/ubuntu/latest_build/abc.war #user##RemoteIP:/var/lib/tomcat7/webapps
You can use a Python script with scp and os library to make a system call.
ssh-keygen -t rsa -b 2048 (local machine)
ssh-copy-id user#remote_server_address
create a Python script like:
import os
cmd = 'scp user#remote_server_address:remote_file_path local_file_path'
os.system(cmd)
create a rule in crontab to automate your script
done
A few people have mentioned sshpass but not many clear coding examples...
This is how we are doing it with bash scripts for rsync backups:
sshpass -p "${RSYNC_PASSWORD}" sftp "${RSYNC_USER}"#"${RSYNC_REMOTE_HOST}"
Keep in mind you will have to sudo apt install sshpass before this works properly.

Resources