Search code examples
listexpectscp

Why doesn't this program copy all my files, using scp?


I wrote a little program which, in first case, slices a list of files and directory names so I get a list of files and a list of directories.

#!/usr/bin/expect -f

set mdproot "****"
set mySource "****"
set myDest "****"
set myDirs {}
set myFiles {}
set i 1
set y 0

lappend myDirs [lindex $argv 0]

foreach variable $argv {
    lappend myDirs [lindex $argv $i+1]
    lappend myFiles [lindex $argv $y+1]
    incr y
    incr y
    incr i
    incr i
}

set DIRECTORIES [lsearch -all -inline -not -exact $myDirs {}]
set FILES  [lsearch -all -inline -not -exact $myFiles {}]

#puts "   "
#puts $DIRECTORIES
#puts "   "
#puts $FILES

foreach file $FILES dir $DIRECTORIES  {
    puts " Fichier : $file et repertoire : $dir"
    spawn scp -p "$mySource/$file" "$myDest/$dir"
    expect -re "(.*)assword: " {sleep 1; send -- "$mdproot\r" }
    expect  eof { return}
}

There are my lists:

$argv :

2017-11-30 
2017-11-30_15-10-44_P_8294418.33_Q1 
2017-11-30 
2017-11-30_15-10-44_R_8294418.33_Q1 
2018-03-07 
2018-03-07_09-30-57_R_HOURS_Q1 
2018-04-13 
2018-04-13_13-23-25_R_HOURS_Q1 
2018-05-02 
2018-05-02_11-19-37_R_HOURS_Q1 
2018-03-07 
2018-3-7_9-30-57_P_HOURS_Q1 
2018-04-13 
2018-4-13_13-23-25_P_HOURS_Q1 
2018-05-02 
2018-5-2_11-19-37_P_HOURS_Q1

$DIRECTORIES :

2017-11-30 
2017-11-30 
2018-03-07 
2018-04-13 
2018-05-02 
2018-03-07 
2018-04-13 
2018-05-02

$FILES :

2017-11-30_15-10-44_P_8294418.33_Q1 
2017-11-30_15-10-44_R_8294418.33_Q1 
2018-03-07_09-30-57_R_HOURS_Q1 
2018-04-13_13-23-25_R_HOURS_Q1 
2018-05-02_11-19-37_R_HOURS_Q1 
2018-3-7_9-30-57_P_HOURS_Q1 
2018-4-13_13-23-25_P_HOURS_Q1 
2018-5-2_11-19-37_P_HOURS_Q1

Actually I have 2 problems (3 in the case we count how trash this code is). First, when I run my program, I have my % indicator for each file I am copying and except the last one, they all stop before they get to 100%. Then, I can see that the scp command isn't done on all the files, the program stops pretty much every time at the 4th file.

root@raspberrypi:~# ./recupFileName.sh 

spawn scp -p /root/muonic_data/2017-11-30_15-10-44_P_8294418.33_Q1 marpic@192.168.110.90:/home/marpic/muonic_data/Data_Q1/2017-11-30
marpic@192.168.110.90's password: 
2017-11-30_15-10-44_P_8294418.33_Q1            15%   68MB   6.9MB/s   00:53 
spawn scp -p /root/muonic_data/2017-11-30_15-10-44_R_8294418.33_Q1 marpic@192.168.110.90:/home/marpic/muonic_data/Data_Q1/2017-11-30
marpic@192.168.110.90's password: 
2017-11-30_15-10-44_R_8294418.33_Q1            41%   69MB   8.5MB/s   00:11 
spawn scp -p /root/muonic_data/2018-03-07_09-30-57_R_HOURS_Q1 marpic@192.168.110.90:/home/marpic/muonic_data/Data_Q1/2018-03-07
marpic@192.168.110.90's password: 
2018-03-07_09-30-57_R_HOURS_Q1                 82%   51MB   7.2MB/s   00:01 
spawn scp -p /root/muonic_data/2018-04-13_13-23-25_R_HOURS_Q1 marpic@192.168.110.90:/home/marpic/muonic_data/Data_Q1/2018-04-13
marpic@192.168.110.90's password: 
2018-04-13_13-23-25_R_HOURS_Q1                100% 6940KB   6.8MB/s   00:01

As you can see, there should be 8 files copied with 100% accuracy, but there are no error messages so I don't know where to start my research.

EDIT :

I added the "set timeout -1" in my script, but now the script is copying only my first file with 100% accuracy, then stops. Any answers ?

root@raspberrypi:~# ./recupFileName.sh 
 Fichier : 2017-11-30_15-10-44_P_8294418.33_Q1 et repertoire : 2017-11-30
spawn scp -p /root/muonic_data/2017-11-30_15-10-44_P_8294418.33_Q1 marpic@192.168.110.90:/home/marpic/muonic_data/Data_Q1/2017-11-30
marpic@192.168.110.90's password: 
2017-11-30_15-10-44_P_8294418.33_Q1           100%  437MB   7.5MB/s   00:58    
root@raspberrypi:~# 

Solution

  • The problem should be in expect eof. By default the timeout is 10 seconds so expect eof would return after 10 seconds though the scp is still running.

    You can use a larger timeout.

    Option #1:

    # set the default `timeout'
    set timeout 3600 ; # or -1 for no timeout
    

    Option #2:

    expect -timeout 3600 eof
    

    Note that your

    expect eof { return }
    

    would exit the whole script so the foreach loop runs for only once, you need just

    expect eof