Need help creating a script for file transferring, or if you know a GUI or CLI program that can do all the below,

Previous post deleted because of improvement/editing of post.

What I need to do: The script will copy and paste a folder/file to another location, and also check & verify to make sure all data was copied successfully and no corruption or errors, and if successful and no corruption, i want it to give me the option to just copy the data(no deleting), or actually cut/paste and delete the original source. And also create an error log inside the folder that the bash script is in, if any errors.

Once I run the bash script I need it to ask me the source file/folder.
Then ask me the destination file path.

Then it will estimate the time it will take and tell me what that will be, before initiating.

Then it will ask me y or n to proceed.

It also has a progress bar that shows the progress of the transfer in the terminal.

It will also have an alarm when the transfer is complete, and use an audio file that is in the same folder as the bash script. And the alarm sound can be stopped by pressing the space bar.

I asked both Gemini and Bing A.I. to create this script, it chose to use bash rather than python, and they both said it will work. It doesnt work. Just wanted to run this by the group to see if anyone wanted to improve on it/fix it.

#!/bin/bash

# Function to play sound and allow stopping with space key

play_sound_with_stop() {

local script_dir=$(dirname "$0")

local sound_file=$(find "$script_dir" -name "*.mp3" | head -n 1)

if [ -f "$sound_file" ]; then

sudo ffplay -nodisp -autoexit "$sound_file" &

sound_pid=$!

echo "Press the space key to stop the alarm."

while kill -0 $sound_pid > /dev/null 2>&1; do

read -n 1 -s key

if [[ $key == " " ]]; then

sudo kill $sound_pid

echo "Alarm stopped."

break

fi

done

else

echo "No MP3 file found in the script directory."

fi

}

# Function to get a valid folder path from the user

get_valid_folder() {

local folder

while true; do

read -p "Enter $1 folder: " folder

if [ -d "$folder" ]; then

echo "$folder"

break

else

echo "No such file or directory. Please try again."

fi

done

}

# Get source and destination folders from user

source_folder=$(get_valid_folder "source")

destination_folder=$(get_valid_folder "destination")

# Ask user if they want to copy or cut (move) the data

read -p "Do you want to copy or cut (move) the data? (copy/cut): " transfer_type

# Estimate transfer speed (assuming a fixed transfer speed for simplicity)

total_size=$(du -sb "$source_folder" | awk '{print $1}') # Get total size of source folder in bytes

transfer_speed=100000000 # 100 MB/s in bytes (adjust as needed)

estimated_time=$(echo "scale=2; $total_size / $transfer_speed" | bc -l) # Estimate time in seconds

echo "Estimated transfer time: $estimated_time seconds (This is a rough estimate)"

# Define the log file path

log_file="$(dirname "$0")/error_log.txt"

# rsync command with options

read -p "Proceed with transfer? (y/N) " -r response

if [[ $response =~ ^([Yy])$ ]]; then

sudo rsync -av --checksum --log-file="$log_file" --protect-args "$source_folder/" "$destination_folder/" | pv -W . &

transfer_pid=$!

# Print continuously updated estimated time remaining

while kill -0 $transfer_pid > /dev/null 2>&1; do

elapsed_time=$(ps -p $transfer_pid -o etimes=)

remaining_time=$(echo "scale=2; $estimated_time - $elapsed_time" | bc -l)

echo "Estimated time remaining: $remaining_time seconds"

sleep 2 # Update time every 2 seconds

done

# Check rsync exit status and provide specific error messages

exit_code=$?

if [ $exit_code -eq 0 ]; then

echo "Transfer completed successfully."

play_sound_with_stop # Play sound notification with stop functionality

if [[ $transfer_type == "cut" ]]; then

sudo rm -rf "$source_folder" # Remove source folder only if transfer was successful and user chose to cut

fi

else

echo "Transfer failed with exit code $exit_code. Please refer to rsync documentation for details."

fi

fi

I was going to suggest rsync but this script is using it.

What error occurs with this script?

rsync has an option to show progress (--progress), so I don't think the script needs to do this or try to estimate how long it will take.

1 Like

Thanks! I just now told bing A.I. to fix it to where it uses rsync's "--info=progress2".

"--progress" does not appear to be what my script needs?

Still I am having the same problem, when the terminal asks for my source file path, it wont accept it, my file path is: "/home/username123/Downloads/editing folder,posters,projects/1/123"

There is a space after "/editing", the problem may be that I need to use double quotes or an apostrophe encasing the file path. Or the script isnt translating that properly. I had to keep telling A.I. to fix it and improve so that it could accept file paths that have spaces in them, not easy. I did manage to recently,one time, to get A.I. to alter the script to where it would accept my file path, and then it moved on and asked for my destination file path and that worked too, but the next step gave me a new error in the script that came up. Unfortunately my terminal history isnt saved or logged,that i know of, so i cant look at old terminal sessions. So I dont have that script anylonger.

Anyways, look below for my updated script, I updated the rsync progress bar in it, but I still get stuck at the 1st prompt, asking me for a source file path. Also i just tested a file path that has no spaces and it still didnt work and still is stuck. Here is the 2nd filepath I tried: "/home/username123/Downloads/Envelope-106883"

#!/bin/bash

# Function to play sound and allow stopping with space key
play_sound_with_stop() {
    local script_dir=$(dirname "$0")
    local sound_file=$(find "$script_dir" -name "*.mp3" | head -n 1)
    if [ -f "$sound_file" ]; then
        sudo ffplay -nodisp -autoexit "$sound_file" &
        sound_pid=$!
        echo "Press the space key to stop the alarm."
        while kill -0 $sound_pid > /dev/null 2>&1; do
            read -n 1 -s key
            if [[ $key == " " ]]; then
                sudo kill $sound_pid
                echo "Alarm stopped."
                break
            fi
        done
    else
        echo "No MP3 file found in the script directory."
    fi
}

# Function to get a valid folder path from the user
get_valid_folder() {
    local folder
    while true; do
        read -p "Enter $1 folder: " folder
        if [ -d "$folder" ]; then
            echo "$folder"
            break
        else
            echo "No such file or directory. Please try again."
        fi
    done
}

# Get source and destination folders from user
source_folder=$(get_valid_folder "source")
destination_folder=$(get_valid_folder "destination")

# Ask user if they want to copy or cut (move) the data
read -p "Do you want to copy or cut (move) the data? (copy/cut): " transfer_type

# Define the log file path
log_file="$(dirname "$0")/error_log.txt"

# Estimate transfer time using rsync dry run
echo "Estimating transfer time..."
sudo rsync -av --checksum --info=progress2 --dry-run --log-file="$log_file" --protect-args "$source_folder/" "$destination_folder/" | grep -E 'total size is|speedup is'

# Ask user to proceed based on the estimate
read -p "Proceed with transfer? (y/N) " -r response
if [[ $response =~ ^([Yy])$ ]]; then
    sudo rsync -av --checksum --info=progress2 --log-file="$log_file" --protect-args "$source_folder/" "$destination_folder/" &
    transfer_pid=$!

    # Monitor the rsync process
    while kill -0 $transfer_pid > /dev/null 2>&1; do
        sleep 2 # Update every 2 seconds
    done

    # Check rsync exit status and provide specific error messages
    exit_code=$?
    if [ $exit_code -eq 0 ]; then
        echo "Transfer completed successfully."
        play_sound_with_stop # Play sound notification with stop functionality
        if [[ $transfer_type == "cut" ]]; then
            sudo rm -rf "$source_folder" # Remove source folder only if transfer was successful and user chose to cut
        fi
    else
        echo "Transfer failed with exit code $exit_code. Please refer to rsync documentation for details."
    fi
fi

There are many things to check.

  1. What error occurs when running?

  2. Does the path of the file/directory you are reporting exist?

  3. How is the script running? With sudo or not?
    Example: sudo ./myscript.sh

1 Like

Same error as i mentioned before that I've always gotten.

And thanks for the advice, i ran it as sudo, but it still gave me the same problem/error.

And yes, of course, the file path exists.

"username123@username123:~$ sudo '/home/username123/Downloads/editing folder,posters,projects/1/dry run.sh'
[sudo] password for username123:
Enter source folder: '/home/username123/Downloads/editing folder,posters,projects/1/123'
Enter source folder:
"

Always use dashes when naming files and folders using details.
editing-posters-projects for example.
Spaces in Unix like systems can be white noise.
Commas can be a brace expansion.
So use dashes liberally to avoid read-conflicts.

You can see terminal history by typing

history

in terminal or just opening the ~.bash_history file in your home directory (use ctl+h to reveal "hidden" system files that have the dot in front of the name in Home Directory).

1 Like

As said by @Aravisian, it would be better to standardize the folder naming.

Spaces and commas are not a good practice. This is why you are having some problems.

The script name itself should not contain spaces: "dry run.sh"
It would be much better: "dry-run.sh" or "dryrun.sh'"

After that I would do it in parts. First make the script that requests the folders is working. Then continue with the rest.

My suggestion is instead of requesting the paths, pass them as parameters.

Something like:
dryrun.sh /home/my/source/path /home/my/dest/path

Another option is to use a tool that already does what you need.
Maybe a GUI for rsync?

1 Like

@Aravisian , @macfly , thanks everyone for the help. Someone told me about Grsync, and that appears to work really well, its GUI too. :slight_smile: So I will use that for now. It does a verification of no data loss too. I'll leave this post as unsolved still, in case someone comes by and wants to make the script 100% working. I put a lot of time in putting the script together, a lot of time talking to A.I. and getting it to rewrite the script about 30 times.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.