Question

I am connecting to remote system through sftp using expect. I want to get the the last modified date of the file my.csv into a variable in expect script

Below is my code:

 spawn sftp -o Port=$port $user@$host
 expect "Password:"
 send "$password\r";
 expect "sftp> "
 set file_time [exec ls -la my.csv| awk {{ print $6$7$8}}]
 send "echo $file_time\r";
 expect "sftp> "
 send "quit\r";
 expect eof
Was it helpful?

Solution

Ok, I took a harder look at this. I see a few things wrong:

  1. When you exec ls -la you are doing so on your local machine... not on the remote sftp server. If you want to execute that on the sftp server you need to use 'send' so that it will be sent over the spawned session.
  2. If you were to use 'send', then you can't pipe it through awk since that ls will be an sftp server command, and there's no awk on the sftp server interface.
  3. Last, I don't think sending echo output to the spawned sftp session is what you want. I'm guessing you want it displayed on the local machine. So the TCL command 'puts' is what you want there.

So what you need to do is send the ls command to the sftp server, then use expect with a regular expression to snatch the timestamp from the returned output.

There's probably more elegant ways to skin this cat, but assuming English language for the months, and that your filename is always identical (my.csv), here's a working variant (on TCL 8.4.13) of that script:

spawn sftp user@host
expect "assword:"
send "mypassword\r";
expect "sftp>"
send "ls -la my.csv\r"
expect -re "\[-rwx\]{10}.*((Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec).*)my.csv"
set timestamp $expect_out(1,string)
expect "sftp>"
send "quit\r";
expect eof
puts "Timestamp is: $timestamp"

I'll leave error control, handling timeouts and all that good stuff to you. :-)

Let me know if that worked out in your environment.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top