I am writing a script to scp some files but need to pass file location through the user or another script as an argument


set FILEPATH1 $1

spawn sh "scp $FILEPATH1 $USER@$HOST:/destination/files"
        set pass "pass123"
        expect {
        password: {send "$pass\r"; exp_continue}

also tried this before the spawn and before the #!/usr/bin/expect


1 Answer 1


This isn't doing what you want:

set FILEPATH1 $1

Tcl (and expect) don't use the shell-style $1, $2, ... way of accessing the command line arguments. You want to use the global $argv list:

set FILEPATH1 [lindex $argv 0]

Also, your spawn call is incorrect. sh will be looking for a file named "scp $FILEPATH1 $USER@$HOST:/destination/files". You don't need a shell to spawn scp:

spawn scp $FILEPATH1 $USER@$HOST:/destination/files

Now, where are USER and HOST coming from? Are they environment variables? If so:

spawn scp $FILEPATH1 $env(USER)@$env(HOST):/destination/files

And, you're not waiting for the transfer to actually complete before your script exits. Do this:

expect password:
send "$pass\r"
set timeout -1
expect eof

I'm assuming that you're only prompted for the password once. If you have to enter it multiple times, then

expect {
    password: {
        send "$pass\r"
        set timeout -1
  • Thank you for clarification and modifications it helped too, Answering your question "Now, where are USER and HOST coming from?" - I am entering them manually for now but looking forward to get current user's USER and put the Password as an argument later to avoid exploiting my password publicly as my team dont have the ability for private-public keys and the script will be used by more than one member, any help in that matter will be apreciated :-)
    – OmAr
    Commented Apr 22, 2019 at 16:56

You must log in to answer this question.

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