A simple mv command in a BASH script

Learn a simple mv command in a bash script with practical examples, diagrams, and best practices. Covers bash, file, mv development techniques with visual explanations.

Mastering the mv Command in Bash Scripts for File Management

Hero image for A simple mv command in a BASH script

Learn how to effectively use the mv command within Bash scripts to move and rename files and directories, ensuring robust and automated file operations.

The mv command is a fundamental utility in Unix-like operating systems, primarily used for moving or renaming files and directories. When integrated into Bash scripts, mv becomes a powerful tool for automating file management tasks, from organizing downloaded content to structuring project directories. This article will guide you through the basics of using mv in a script, common pitfalls, and best practices for robust file operations.

Basic Usage of mv in a Script

At its core, the mv command takes two main arguments: the source path(s) and the destination path. When moving a single file, the destination can be a new filename (for renaming) or a directory. When moving multiple files, the destination must be a directory. In a script, these paths are often derived from variables or command-line arguments.

#!/bin/bash

SOURCE_FILE="report.txt"
DEST_DIR="archive"
NEW_NAME="final_report_$(date +%Y%m%d).txt"

# Create dummy file and directory for demonstration
mkdir -p "$DEST_DIR"
echo "This is a test report." > "$SOURCE_FILE"

# 1. Move a file to a directory
echo "Moving '$SOURCE_FILE' to '$DEST_DIR/'..."
mv "$SOURCE_FILE" "$DEST_DIR/"

# 2. Rename a file within the same directory
echo "Renaming 'old_name.log' to 'new_name.log'..."
echo "Log content" > old_name.log
mv old_name.log new_name.log

# 3. Move and rename a file simultaneously
echo "Moving and renaming 'new_name.log' to '$DEST_DIR/$NEW_NAME'..."
mv new_name.log "$DEST_DIR/$NEW_NAME"

# Clean up
rm -rf "$DEST_DIR"

Examples of mv command usage in a Bash script.

Handling Overwrites and Errors

By default, mv will overwrite an existing destination file without prompting if the user has write permissions. In scripts, this behavior can be dangerous. It's crucial to implement checks or use mv options to prevent accidental data loss. The -i (interactive) option prompts before overwriting, and -u (update) only moves when the source is newer than the destination or the destination does not exist. The -n (no-clobber) option prevents overwriting existing files.

#!/bin/bash

FILE_TO_MOVE="document.txt"
DEST_PATH="./archive/document.txt"

mkdir -p archive
echo "Original content" > "$FILE_TO_MOVE"
echo "Existing content" > "$DEST_PATH"

echo "Attempting to move with -n (no-clobber):"
mv -n "$FILE_TO_MOVE" "$DEST_PATH"

if [ $? -eq 0 ]; then
    echo "Move successful or file already existed and was not overwritten."
else
    echo "Move failed or file existed and was not overwritten (expected behavior with -n)."
fi

# Clean up
rm -rf archive "$FILE_TO_MOVE"

Using mv -n to prevent accidental overwrites.

flowchart TD
    A[Start Script] --> B{Check if Source Exists?}
    B -- No --> C[Error: Source Not Found]
    B -- Yes --> D{Check if Destination Exists?}
    D -- Yes --> E{Overwrite Allowed?}
    E -- No (e.g., mv -n) --> F[Skip Move / Error]
    E -- Yes --> G[Perform Move/Rename]
    D -- No --> G
    G --> H[End Script]
    C --> H
    F --> H

Decision flow for the mv command, including overwrite considerations.

Best Practices for Robust mv Operations

When scripting with mv, consider these practices to make your scripts more reliable and user-friendly:

  1. Always Quote Variables: As mentioned, this prevents issues with spaces and special characters in filenames.
  2. Check for Existence: Before moving, verify that the source file/directory exists and the destination directory is writable. This prevents mv from failing unexpectedly.
  3. Error Handling: Check the exit status of mv (using $?) to determine if the command succeeded. A non-zero exit status indicates an error.
  4. Use -v for Verbose Output: The -v (verbose) option prints what mv is doing, which is very helpful for debugging scripts.
  5. Consider rsync for Complex Moves: For moving large files, across networks, or with more advanced synchronization needs, rsync can be a more robust alternative, offering features like progress indicators and checksum verification.
#!/bin/bash

SOURCE="my_document.pdf"
DESTINATION_DIR="/home/user/documents/processed"

# Create dummy file for demonstration
echo "PDF content" > "$SOURCE"

# Check if source exists
if [ ! -f "$SOURCE" ]; then
    echo "Error: Source file '$SOURCE' not found." >&2
    exit 1
fi

# Check if destination directory exists and is writable
if [ ! -d "$DESTINATION_DIR" ]; then
    echo "Error: Destination directory '$DESTINATION_DIR' not found." >&2
    exit 1
elif [ ! -w "$DESTINATION_DIR" ]; then
    echo "Error: Destination directory '$DESTINATION_DIR' is not writable." >&2
    exit 1
fi

# Perform the move with verbose output and error checking
echo "Attempting to move '$SOURCE' to '$DESTINATION_DIR/'..."
mv -v "$SOURCE" "$DESTINATION_DIR/"

if [ $? -eq 0 ]; then
    echo "Successfully moved '$SOURCE'."
else
    echo "Failed to move '$SOURCE'." >&2
    exit 1
fi

# Clean up (if the move was successful, SOURCE will be gone)
# If move failed, SOURCE might still exist, so remove it.
rm -f "$SOURCE" # This will only remove if it still exists
rmdir "$DESTINATION_DIR" 2>/dev/null # Remove dir if empty, suppress error if not

A more robust mv script with checks and error handling.