Reputation: 5
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