am I required to use spawn when using expect? - linux

I am creating a simple automated script. here is the code
#!/bin/sh
echo "testing expect"
/usr/bin/expect <<delim
expect "password for teamer:"
send "itsme\r"
expect eof
delim
sudo apt-get update
I refer to various documents and blogs they are using spawn. So I have question: is it necessary to use spawn every time? I am executing the update on my local machine.
Not using spawn I get this error:
send: spawn id exp0 not open while executing
or am I missing something?

expect's expect command is watching the IO channels of the spawned process waiting for the pattern to specify. If you don't give it something to watch, it will just sit there until it times out and then send the password to nothing.
This is what you need to do:
#!/bin/sh
echo "testing expect"
/usr/bin/expect <<delim
exp_internal 1 ;# remove this when your satisfied it's working
spawn sudo apt-get update
expect "password for teamer:"
send "itsme\r"
expect eof
delim
Be careful that you do not have any leading or trailing whitespace on the line with the heredoc delimiter.
If you don't care that your password is in plain text (you should), you don't need to use expect:
#!/bin/sh
echo "itsme" | sudo -S apt-get update
What you ought to do is to edit the sudoers file to allow yourself to sudo apt-get without having to supply your password, then:
#!/bin/sh
sudo apt-get update
Read the sudoers man page on your system.

Related

expect: couldn't execute "/usr/bin/zypper patch": no such file or directory

I wrote an expect script
vi /foo/force-zypper-patch.exp
cat /foo/force-zypper-patch.exp
#!/usr/bin/expect
set timeout 300
spawn "/usr/bin/zypper patch"
expect "Continue? [y/n/...? shows all options] (y): " { send "y\r" }
interact
but even though I have the zypper with full path, it fails:
SERVER1:~ # ssh SERVER2 "/usr/bin/expect -f /foo/force-zypper-patch.exp"
spawn /usr/bin/zypper patch
couldn't execute "/usr/bin/zypper patch": no such file or directory
while executing
"spawn "/usr/bin/zypper patch""
(file "/foo/force-zypper-patch.exp" line 4)
SERVER1:~ #
SERVER1:~ # ssh SERVER2 "which zypper"
/usr/bin/zypper
SERVER1:~ #
although I can reach my purpose with a "zypper patch -y --with-interactive" but I would be really interested, how to do this in expect!
Simply remove the quotes from the spawn line.
spawn /usr/bin/zypper patch
Currently, you are trying to execute the command zypper patch in the /usr/bin directory, and clearly no such file exists.

Pass two password to su commands

I am trying to run shell comment through PHP scripts.
I want to first su into a user then run a sudo command. I tried:
echo mypassword | (su -c "sudo reboot" user2)
It doesn't work because it requires two password and I only passed one password. I checked many other posts, the solution below doesn't work for me because I don't have the sudo password for the current user. I need to change the user a first then do a sudo. Can I get some help?
echo mypassword | sudo -s ... Not work...
I know this is a bad practice. I just need it to restart server as the port 22 is closed accidentally. I can't ssh into the server to do any operations..
This is ONE time use to reboot the server from PHP side as I am not able to reach the admin to reboot the server right now. I fully understand the disadvantages... Please DO NOT suggest the disadvantages.
Since it's an one time thing, try to use the following. It spawns a sudo environment (for the current user) in which sudo reboot is called.
#! /bin/bash
read -sp "pass? " pass
expect 2>&1 <<-EOF
spawn sudo reboot
expect "*: " { send "${pass}\r" }
expect eof
catch wait result
exit [lindex \$result 3]
EOF
exit $?
You can call it as follows to automate stuff.
$ ./test.sh <<-EOF
notreallymypassword
EOF
Note: Although I think it works, I haven't tested it yet.

Bash script to respond to console output?

Currently trying to run a bash script on startup to automatically install squid, however the command I'm running requires input.
Currently the script i have is:
#!/bin/sh
PROXY_USER=user1
PROXY_PASS=password1
wget https://raw.githubusercontent.com/hidden-refuge/spi/master/spi && bash spi -rhel7 && rm spi
#After i run this command it asks "Enter username"
#followed by "Enter password" and "Renter password"
echo $PROXY_USER
echo $PROXY_PASS
echo $PROXY_PASS
echo yes
However i am unable to get the input working, and the script fails to create a username and password. I'm running centos 7.
Look you are calling some tools which act in interactive mode, so as dani-gehtdichnixan mentioned at (passing arguments to an interactive program non interactively) you can use expect utilities.
Install expect at debian:
apt-get install expect
Create a script call spi-install.exp which could look like this:
#!/usr/bin/env expect
set user username
set pass your-pass
spawn spi -rhel7
expect "Enter username"
send "$user\r"
expect "Renter password"
send "$pass\r"
Then call it at your main bash script:
#!/bin/bash
wget https://raw.githubusercontent.com/hidden-refuge/spi/master/spi && ./spi-install.exp && rm spi
Expect is used to automate control of interactive applications such as Telnet, FTP, passwd, fsck, rlogin, tip, SSH, and others. Expect uses pseudo terminals (Unix) or emulates a console (Windows), starts the target program, and then communicates with it, just as a human would, via the terminal or console interface. Tk, another Tcl extension, can be used to provide a GUI.
https://en.wikipedia.org/wiki/Expect
Reference :
[1] passing arguments to an interactive program non interactively
[2] https://askubuntu.com/questions/307067/how-to-execute-sudo-commands-with-expect-send-commands-in-bash-script
[3] https://superuser.com/questions/488713/what-is-the-meaning-of-spawn-linux-shell-commands-centos6
Try just passing the values to bash's stdin
#!/bin/sh
PROXY_USER=user1
PROXY_PASS=password1
if wget https://raw.githubusercontent.com/hidden-refuge/spi/master/spi; then
printf "%s\n" "$PROXY_USER" "$PROXY_PASS" "$PROXY_PASS" yes | bash spi -rhel7
rm spi
fi

Hide plaintext password from showing in bash script?

I have the following bash script to restart the network manager in Debian. The script works as is it should, but not as I would like it to. When the script asks for the sudo password I am able to pass it along using echo, but it displays the password in terminal while the script executes, making it less asthetically pleasing than I would like. Is there anyway to have the script enter the password, but not display the password text while the script calls for the sudo password?
I have tried as many suggestions on Stack Overflow as i could find, well as Stack Exchange before submitting this question.
Script is as follows:
#!/bin/bash
clear
echo "Restarting service Network Manager"
echo""
sleep 1
echo -e "\033[0;31m......................................\033[0m"
echo -e "\033[0;31m......................................\033[0m"
sleep 1
echo""
sudo service network-manager restart
sleep 2
echo <Password>
sleep 2
echo "Service Network Manager Restarted"
sleep 1
echo ""
echo "Relinquishing control of terminal to user..."
sleep 7
clear
Remove the echo <Password> line? I am pretty sure it does nothing other than display the password, as sudo apparently (through an appropriate entry in /etc/sudoers) works without you having to give a password. (What you write to terminal with echo does not get passed to any other process.)
Generally speaking, you can use sudo -S to make sudo expect the password on stdin. But also generally speaking, if you have to hardcode a password in a script, you're doing it wrong in some way.
Is there anyway to have the script enter the password
Putting password in script is not a good idea. First, from security point of view, password may be recovered from script from anyone with access to script. Second, from maintenance view, once you change your password, scripts suddenly stop working and you have to update them all.
Fortunately, as you are already using sudo there is better solution. You can configure sudo to allow running certain command without password, by using NOPASSWD rule in /etc/sudoers.
myuser ALL=(ALL) NOPASSWD: service network-manager restart
See:
How do I run specific sudo commands without a password?
How to run a specific program as root without a password prompt?
Warning: Always edit /etc/sudoers with visudo, never directly. It prevents you from breaking /etc/sudoers. Once you break your /etc/sudoers, you won't be able to use sudo, including using sudo to fix /etc/sudoers.
try this /bin/echo -e "password\n" | sudo apt-get update
or see this Use sudo with password as parameter

Is it possible to run multiple command with remote command option in putty?

I want to run multiple commands automatically like sudo bash, ssh server01, ls , cd /tmp etc at server login..
I am using Remote command option under SSH in putty.
I tried multiple commands with delimiter && but not working.
There is a some information lacking in your question.
You say you want to run sudo bash, then ssh server01.
Will sudo prompt for a password in your remote server?
Assuming there is no password in sudo, running bash will open another shell waiting for user input. The command ssh server01 will not be run until that bash shell is exited.
If you want to run 2 commands, try first simpler ones like:
ls -l /tmp ; echo "hi there"
or if you prefer:
ls -l /tmp && echo "hi there"
Does this work?
If what you want is to run ssh after running bash, you can try :
sudo bash -c "ssh server01"
That is probably because the command is expected to be a program name followed by parameters, which will be passed directly to the program. In order to get && and other functionality that is provided by a command line interpreter such as bash, try this:
/bin/bash -c "command1 && command2"
I tried what I suggested in my previous answer.
It is possible to run 2 simple commands in putty separated by a semicolon. As in my example I tried with ls and echo. The remote server runs them and then the session closes.
I also tried to ssh to a remote server that is configured for not asking for a password. In that case, it also works, I get connected to the 2nd server and I can run commands on it. Upon exit, the 2 connections are closed.
So please, let us know what you actually need / want.
You can execute two consecutive commands in PuTTY using a regular shell syntax. E.g. using ; or &&.
But you want to execute ssh server01 in sudo bash shell, right?
These are not two consecutive commands, it's ssh server01 command executed within sudo bash.
So you have to use a sudo command-line syntax to execute the ssh server01, like
sudo bash ssh server01

Resources