I’m currently teaching at the Summmer School in Statistical Omics in Split, Croatia. A great experience!
Because of the computations involved in the project work, we have access to a server. However, since the machine is part of a university cluster, I haven’t been given full root permissions (in fact, I’m only allowed to use sudo
to install packages).
Now, the problem I had to solve was that I needed to distribute a certain file (.Renviron
) to each student’s home directory. Normally I’d use sudo
to do that, but the admin hadn’t allowed me to use cp
via sudo
. Furtunately, I had a list of user names and passwords for the students (because I had to distribute those), so I thought I’d use su -
to change to each student’s account and copy the file, something along the lines of
and then loop over each account. Unfortunately, while testing the script I found out it wouldn’t work since su
complained:
su: must be run from a terminal |
su: must be run from a terminal
Then I remembered the expect
tool, which executes commands based on what it ‘sees’ on the command line. In this case I wanted it to enter the password at su
‘s prompt. This is the expect script I came up with, it accepts two command line arguments, the user name and the password:
#!/usr/bin/expect -f
set user [lindex $argv 0]
set pass [lindex $argv 1]
spawn su - $user
expect "Password: "
send "$pass\r"
expect "$ "
send "cp -i /common/WORK/school/lennart/.Renviron .\r"
expect "$ "
send "ls -l .Renviron\r"
expect "$ "
send "exit\r" |
#!/usr/bin/expect -f
set user [lindex $argv 0]
set pass [lindex $argv 1]
spawn su - $user
expect "Password: "
send "$pass\r"
expect "$ "
send "cp -i /common/WORK/school/lennart/.Renviron .\r"
expect "$ "
send "ls -l .Renviron\r"
expect "$ "
send "exit\r"
The script was wrapped in the Bash script that I had already written:
#!/bin/bash
#
# This script is used to copy files from this directory to the
# home directories of the users listed in $USERFILE.
USERFILE=accounts.txt
SRCFILE=/common/WORK/school/lennart/.Renviron
while read user passw; do
./copy_file_to_users.expect $user $passw
done < $USERFILE |
#!/bin/bash
#
# This script is used to copy files from this directory to the
# home directories of the users listed in $USERFILE.
USERFILE=accounts.txt
SRCFILE=/common/WORK/school/lennart/.Renviron
while read user passw; do
./copy_file_to_users.expect $user $passw
done < $USERFILE
Related Images: