1

I have worked for a while on making a BASH script to go through two lists and creating a command out of it.

In the end it should execute the command and synchronize my ZFS server and ZFS backup server.

Only pinnacle is that BASH cant actually insert a password when a command ask's for it.

To my understanding this can be achieved with expect.

The command is stored in $ExecuteSyncoid And would look like this

/usr/sbin/syncoid <UserName>@<IP>:Storage/WallaBag Storage/Docker/WallaBag --compress none --sshcipher [email protected] --sshport <PortNumber> --sshkey </dest/to/keyfile> --no-privilege-elevation

The password is stored in $PWD

now i have to execute the expect from within BASH since im not really in the mood to try and recreate all the code in expect/tcl which i have never tried before.

The expect part is

Enter passphrase for key '<nameOfKey>'

Now i dont understand tcl/expect But I have made the attempts so far and i just cant make it work even one time

expect -c 'expect "Enter" { spawn $ExecuteCommand; send -- "$PWD\r"; interact }'


expect -c 'spawn $ExecuteSyncoid; expect "Enter"; send -- "$PWD\r"; interact'


syncoid command/password
/usr/bin/expect - <<EOF
    spawn $ExecuteSyncoid
    expect "Enter"
    send -- "$PWD\r"
EOF


/usr/bin/expect <<EOD
spawn $ExecuteSyncoid
expect "Enter passphrase for key"
send -- "$PWD\r"
interact
EOD


/usr/bin/expect -c 'expect "Enter" { spawn $ExecuteSyncoid; send -- "$PWD\r" }'

I Allso attempted to make a seperate script

expect -f ./SynCoid-IterateThroughDataSets.exp $ExecuteSyncoid $PWD

With the code

#!/usr/bin/expect -f 
set ExecuteSyncoid [lindex $argv 0];
set PWD [lindex $argv 1];
spawn $ExecuteSyncoid
expect "Enter"
send "\$PWD\r"

But unfortunately i cant figure out how to make expect see the $ExecuteSyncoid command as one consistent command. It wont execute it if i put it in quotos "" and if i dont have it in quotes the $ExecuteSyncoid bash variable is considered multiple arguments in expect.


If anyone knows how to fix this, Or have an idea about what to do i would appreciate it.

Would allso be great if i could sse the output of the expect command as it executes $ExecuteSyncoid

Best Regards, Darkyere

1
  • "The password is stored in $PWD" no it's not - that's a reserved variable for the current directory. Use a different (lowercased) variable name, and double quote your variables when you use them in a shell script
    – roaima
    May 21, 2022 at 8:14

1 Answer 1

1

I'm not going to review every variant. However shell variables don't expand within single quotes.

Looking at the last variation:

The shell part

ExecuteSyncoid="/usr/sbin/syncoid <UserName>@<IP>:Storage/WallaBag Storage/Docker/WallaBag --compress none --sshcipher [email protected] --sshport <PortNumber> --sshkey </dest/to/keyfile> --no-privilege-elevation"
PassWord="abc123"      # Don't use PWD!

expect -f ./SynCoid-IterateThroughDataSets.exp $ExecuteSyncoid $PassWord

Because the variables are not quoted, they experience Word Splitting: expect script will see 13 arguments, not 2.

Always quote your variables:

expect -f ./SynCoid-IterateThroughDataSets.exp "$ExecuteSyncoid" "$PassWord"

The expect part

#!/usr/bin/expect -f 
set ExecuteSyncoid [lindex $argv 0];
set PWD [lindex $argv 1];          # this has nothing to do with the shell's PWD variable
spawn $ExecuteSyncoid
expect "Enter"
send "\$PWD\r"

Now that the shell variables are quoted, the expect variable ExecuteSyncoid is a single word that contains spaces.

The spawn command will need that word expanded, so we'll use Tcl's Argument expansion syntax:

spawn {*}$ExecuteSyncoid

You don't want to escape the expect PWD variable when you send it: remove the first backslash

send "$PWD\r"

And unless you do something else in expect, after you send the password, the expect script will exit and that will kill the syncoid process. The last line of the expect script should be one of:

  • if you, the human, need to interact with syncoid
    interact
    
  • if you don't need to interact
    expect eof
    
1
  • Thank you alot for this. This made the script work and i finally synced my ZFS test's machines. I would never have figured out the part about {*}$ExecuteSyncoid TCL's parameter expansion. And wouldten have guessed $PWD would have been considered a shell variable. I just thought i created my own variable honestly. It was a great step forward for my ZFS replication backup. I highly appreciate it. Thank you :)
    – Darkyere
    May 22, 2022 at 16:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .