Help with bash/expect
Hi Folks,
I have made a bash script which ssh's to a number of servers (IPs are read from a text file) and adds users with a specified username and userid. The user details are also read from a text file. So I am basically running nested for loops (once for Host IP and once for each line in user_list). The script is working as expected, only letdown being the password prompts. For each IP the password is prompted twice (first time for ssh and second time for sudo). I would very much like to use an expect script to automate the credentials part. I have no prior experience with expect and I could not find examples of nested loop or string manipulation (when read from a file) in expect. Here's my working bash script [some details have been omitted] Code:
#!/bin/bash A. How may I use nested for loops in expect ? B. How may I use string manipulation from file ? [my user details are kept on a text file in USERNAME:USERID format. I would like to know if I may use something like awk -F: '{print $1/$2}' FILENAME] C. Is there any way I can call an expect script to this position (###) and provide the passwords ? Note: 1. I am not looking for a solution with sshpass /ssh keypair. 2. My environment is a CentOS 6.9 VM. Openssh -> 5.3p1-123.el6_9, bash -> 4.1.2-48.el6, expect -> 5.44.1.15-5.el6_4 |
expect is an extension of Tcl, you can use any of its built in commands as well as calling an external command like awk.
Tcl does have a split function. You can use nested loops in Tcl similar to any other language. I have not tried using sudo in an expect script. You can write your entire script in Tcl/expect, you can execute via expect -c "cmds" or use a heredoc as bash. Some documentation. https://www.tcl.tk/doc/ https://www.tcl.tk/man/expect5.31/expect.1.html |
There are some mistakes in the script:
The for loops take a list; they are not good in reading lines. A space in the user_list can spoil everything. A while-read loop is much better. The exit status of ssh is not related to the exit status of the remotely run commands. The following proposal also tries to combine the remote comands into one ssh command; would be more sufficient. Code:
#!/bin/bash Code:
echo 'adding $USR with ID $USRID to $ip' Code:
echo " -- Regarding the password setting, you should use the chpasswd command, that reads it from stdin by default. Like this: Code:
echo "user:password" | chpasswd |
Thanks for your attention.
@MadeInGermany, I actually do have a sed snippet to handle leading/trailing whitespaces {sed -e 's/^[ \t]*//' -e 's/[ \t]*$//'}. I could not post the whole script for workplace reasons, but I provided a bare-bone version to show my efforts. I shall try out your recommendation with while loop. :) @michaelk, Thanks for the links, but documentation and manual pages were the first thing where I checked. Hope there were more examples for expect (much like nmcli-examples, wishful thinking :rolleyes:). |
Here is a quick expect heredoc that you can run within bash that shows how to login via ssh and run multiple commands using sudo.
Code:
#!/bin/bash Code:
host=myhost |
FIXED
Thanks @michaelk, This was very helpful. I have added the EOF block with minor modifications to the ### section and it now works flawlessly (albeit with a time delay, so I guess I have to use the set timeout).
Few links for future visitors to this thread in hopes that they find the resources useful - link 1 link 2 link 3 link 4 |
Stuck again on passing bash non-command directives via expect.
I am trying to send something similar to - Code:
#! /bin/bash Code:
send "for j in \$(sudo grep -iP simple_allow_users /etc/sssd/sssd.conf | fmt -1 | grep -Ev "simple|="| sed -e s/,//g); do if ![[ "\$j" =~ ^(AAAAAAA|BBBBBBB|CCCCCCC) ]] && [[ \$j != n* ]] ; then echo "deleting \$j" ; fi; done;/r" Code:
extra characters after close-quote Code:
send "for j in \$(cat /home/someuser/user_list); do if ![[ \"\$j\" =~ ^(AAAAAAA|BBBBBBB|CCCCCCC) ]] && [[ \$j != n* ]] ; then echo \"deleting \$j\" ; fi; done;/r" Environments - A. 2.6.32-696.10.3.el6.x86_64/bash 4.1.2(1)/expect 5.44.1.15-5 (running from) B. 3.10.0-862.11.6.el7.x86_64/bash 4.2.46(2) (target machine) |
Please don't do this... there is newusers(8) for adding multiple users
|
All times are GMT -5. The time now is 07:38 AM. |