YOUNGKYUN OH
YOUNGKYUN OH

Reputation: 5

about expect script to use deleting file in SFTP Server, please help me

I have a question about expect script to use deleting file in SFTP Server.

#!/usr/bin/expect

set sftp_host [lindex $argv 0]
set sftp_user [lindex $argv 1]
set sftp_password [lindex $argv 2]
set target_dir [lindex $argv 3]
set log_file [lindex $argv 4]

proc log_message {message log_file} {
    exec echo "[exec date "+%Y-%m-%d %H:%M:%S"] - $message" >> $log_file
}

log_user 0
exp_internal 0

spawn sftp $sftp_user@$sftp_host

expect {
    -re ".*password:.*" {
        send "$sftp_password\r"
    }
    timeout {
        log_message "Timeout during login" $log_file
        exit 1
    }
}

expect {
    -re ".*sftp.*>" {
        send "cd $target_dir\r"
        expect {
            -re ".*Couldn't canonicalize: No such file or directory.*" {
                log_message "Directory not found: $target_dir, skipping to next" $log_file
                send "bye\r"
                exit 0
            }
            -re ".*sftp.*>" {
                send "ls -l\r"
            }
        }
    }
}

if {[llength $expect_out(buffer)] == 0} {
    log_message "No output from SFTP command for $target_dir" $log_file
    exit 0
}

set dir_stack [list $target_dir]

while {[llength $dir_stack] > 0} {
    set current_dir [lindex $dir_stack end]
    log_message "Current directory: $current_dir" $log_file
    set dir_stack [lrange $dir_stack 0 end-1]
    #log_message "Remaining stack: $dir_stack" $log_file

    expect {
        -re ".*sftp.*>" {
            log_message "Sending command: cd $current_dir" $log_file
            send "cd $current_dir\r"
            expect {
                -re ".*sftp.*>" {  ;
                    log_message "Successfully changed directory to: $current_dir" $log_file
                    send "ls -l\r"
                    expect {
                        -re ".*sftp.*>" {
                            set captured_output $expect_out(buffer)
                            log_message "First captured output: $captured_output" $log_file


                            regsub -all {\r} $captured_output "" clean_output

                            set output_lines [split $clean_output "\n"]
                            set clean_lines [lrange $output_lines 1 end]

                            set final_output [join $clean_lines "\n"]

                            log_message "Final captured output: $final_output" $log_file
                            
                            set skip_delete 0
                            

                            foreach line [split $final_output "\n"] {
                                if {[regexp {^[d-]} $line]} {
                                    set entry [lindex [split $line] end]
                                    set type [string index $line 0]
                                    log_message "entry: $entry" $log_file
                                    log_message "type: $type" $log_file
                                    
                                    if {$type == "d"} {

                                        set sub_dir "$current_dir/$entry"
                                        log_message "Found subdirectory: $sub_dir" $log_file
                                        lappend dir_stack $sub_dir
                                        log_message "Remaining stack in foreach: $dir_stack" $log_file
                                        
    
                                        set skip_delete 1
                                    } else {

                                        log_message "Found file: $entry in $current_dir" $log_file
                                        send "rm $entry\r"
                                        expect {
                                            -re ".*sftp.*>" {}
                                            timeout {
                                                log_message "Failed to delete file: $entry" $log_file
                                            }
                                        }
                                    }
                                }
                            }


                            if {$skip_delete == 0} {
                                log_message "Deleting directory: $current_dir" $log_file
                                send "cd [file dirname $current_dir]\r"
                                expect -re ".*sftp.*>"
                                send "rmdir [file tail $current_dir]\r"
                                expect {
                                    -re ".*sftp.*>" {
                                        log_message "Successfully deleted directory: $current_dir" $log_file
                                    }
                                    timeout {
                                        log_message "Failed to delete directory: $current_dir" $log_file
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

send "bye\r"
log_message "Session closed" $log_file
exit 0

enter image description here enter image description here

I am trying to create an Expect script to execute the following operations for a directory structure:

Navigate through the directory structure recursively or using a while loop. For the deepest directory, delete all items within it. Once all items are deleted, remove the directory itself. Move to the parent directory and repeat the process. While testing the script, I observed that it successfully identifies subdirectories but fails to execute the subsequent logic for cd and ls after identifying a subdirectory. Instead, it waits indefinitely before the session eventually times out.

What could be the cause of this issue, and how can it be resolved?

Upvotes: 0

Views: 50

Answers (0)

Related Questions