Command documentation sourced from the linux-command project This comprehensive command reference is part of the linux-command documentation project.
unlink - Remove directory entry
The unlink command is a basic Unix utility that removes a single file from the filesystem. It calls the unlink() system call, which removes the specified directory entry and decrements the link count of the file. When the link count reaches zero and no process has the file open, the file is actually deleted from the filesystem. Unlike rm, unlink can only remove one file at a time and has no recursive or interactive options. It's a minimal, low-level tool designed for simple file removal operations.
Basic Syntax
unlink [OPTION]... FILE...
Common Options
Basic Options
--help- Display help information and exit--version- Output version information and exit
Behavior
unlinkonly accepts a single filename argument- Cannot remove directories
- No confirmation prompts
- No recursive deletion capability
- Cannot use wildcards or multiple filenames
Usage Examples
Basic File Removal
Simple Unlink Operations
# Remove a single file
unlink myfile.txt
# Remove a file with absolute path
unlink /tmp/tempfile.dat
# Remove a file in current directory
unlink "./document.pdf"
# Attempt to remove directory (will fail)
unlink mydirectory/ # Error: unlink: cannot unlink 'mydirectory/': Is a directory
# Attempt to remove multiple files (will fail)
unlink file1.txt file2.txt # Error: unlink: extra operand 'file2.txt'
Working with Different File Types
# Remove a regular file
unlink regular_file.txt
# Remove a symbolic link (removes the link, not target)
unlink symlink_to_file
# Remove a hard link (decrements link count)
unlink hardlink.txt
# Remove a file with special characters in name
unlink "file with spaces.txt"
unlink "file-with-dashes.txt"
unlink "file_with_underscores.txt"
Filesystem Operations
Understanding Link Behavior
# Create multiple links to same file
echo "content" > original.txt
ln original.txt hardlink1.txt
ln original.txt hardlink2.txt
# Check link count (should be 3)
ls -l original.txt
# Remove one link (file still accessible via other links)
unlink hardlink1.txt
ls -l original.txt # Link count now 2
# Remove all links one by one
unlink hardlink2.txt
unlink original.txt # File actually deleted
Working with Symbolic Links
# Create symbolic link
ln -s /path/to/target.txt symlink.txt
# Remove symbolic link (target file remains)
unlink symlink.txt
# Create broken symbolic link
ln -s nonexistent.txt broken_link.txt
unlink broken_link.txt # Removes broken link
Error Handling
Common Error Scenarios
# Attempt to remove non-existent file
unlink nonexistent.txt # Error: unlink: cannot unlink 'nonexistent.txt': No such file or directory
# Attempt to remove directory
unlink mydir/ # Error: unlink: cannot unlink 'mydir/': Is a directory
# Attempt to remove file without permissions
unlink protected.txt # Error: unlink: cannot unlink 'protected.txt': Permission denied
# Attempt to remove file in use by process
lsof +f -- /tmp/locked_file.txt
unlink /tmp/locked_file.txt # May work or fail depending on system
# Attempt to remove multiple files
unlink file1.txt file2.txt # Error: unlink: extra operand
Safe File Removal
# Check if file exists before unlinking
[ -f "temp_file.txt" ] && unlink temp_file.txt
# Use find with unlink for selective removal
find /tmp -name "*.tmp" -type f -exec unlink {} \;
# Remove files older than 7 days
find /var/log -name "*.log.old" -mtime +7 -type f -exec unlink {} \;
Practical Examples
System Administration
Temporary File Cleanup
#!/bin/bash
# Clean up temporary files safely
# Clean user temporary files
find /tmp -maxdepth 1 -name "tmp.*" -user "$USER" -type f -exec unlink {} \;
# Clean session files
find /tmp -name "session_*" -mtime +1 -type f -exec unlink {} \;
# Clean cache files
find ~/.cache -name "*.cache" -mtime +7 -type f -exec unlink {} \;
echo "Temporary files cleaned successfully"
Log File Management
#!/bin/bash
# Rotate and remove old log files
LOG_DIR="/var/log/myapp"
DAYS_TO_KEEP=30
# Remove old log files
find "$LOG_DIR" -name "*.log.*" -mtime +$DAYS_TO_KEEP -type f -exec unlink {} \;
# Compress and remove uncompressed logs if they exist
if [ -f "$LOG_DIR/application.log" ]; then
gzip "$LOG_DIR/application.log"
unlink "$LOG_DIR/application.log" # Remove original after compression
fi
echo "Log rotation completed"
Process Cleanup
#!/bin/bash
# Remove process lock files
# Remove stale lock files
find /var/lock -name "*.lock" -type f -exec sh -c '
f="$1"
# Check if process is still running
pid=$(cat "$f" 2>/dev/null)
if ! kill -0 "$pid" 2>/dev/null; then
echo "Removing stale lock: $f"
unlink "$f"
fi
' sh {} \;
Development Workflow
Build System Cleanup
#!/bin/bash
# Clean build artifacts using unlink
# Remove object files
find . -name "*.o" -type f -exec unlink {} \;
# Remove compiled binaries
find . -name "a.out" -type f -exec unlink {} \;
# Remove temporary build files
find . -name ".tmp_*" -type f -exec unlink {} \;
# Remove specific build artifacts
[ -f "Makefile.bak" ] && unlink Makefile.bak
echo "Build cleanup completed"
Version Control Operations
#!/bin/bash
# Version control helper functions
# Remove untracked files
git_clean_untracked() {
git ls-files --others --exclude-standard | while read -r file; do
if [ -f "$file" ]; then
echo "Removing: $file"
unlink "$file"
fi
done
}
# Remove merge conflict backup files
remove_conflict_backups() {
find . -name "*.orig" -type f -exec unlink {} \;
find . -name "*.rej" -type f -exec unlink {} \;
}
File Processing
File Processing Pipeline
#!/bin/bash
# Process files and remove originals
for file in *.dat; do
if [ -f "$file" ]; then
# Process the file
processed_file="${file%.dat}.processed"
python process_data.py "$file" > "$processed_file"
# Remove original if processing was successful
if [ -f "$processed_file" ]; then
unlink "$file"
echo "Processed and removed: $file"
fi
fi
done
Backup Verification
#!/bin/bash
# Verify backups and remove temporary files
SOURCE_DIR="/data"
BACKUP_DIR="/backup"
TEMP_DIR="/tmp/backup_verify"
# Create temporary verification file
verify_file="$TEMP_DIR/verify_$(date +%Y%m%d_%H%M%S).txt"
# Perform backup verification
if tar -tf "$BACKUP_DIR/backup.tar.gz" | wc -l > "$verify_file"; then
echo "Backup verification successful"
unlink "$verify_file"
else
echo "Backup verification failed"
# Keep verification file for debugging
fi
Advanced Usage
Script Integration
Batch Processing with Unlink
#!/bin/bash
# Safe batch file removal
safe_unlink() {
local file="$1"
local confirm="${2:-false}"
if [ ! -f "$file" ]; then
echo "Error: File '$file' does not exist"
return 1
fi
if [ "$confirm" = "true" ]; then
read -p "Remove '$file'? [y/N] " response
if [[ ! "$response" =~ ^[Yy]$ ]]; then
echo "Cancelled"
return 0
fi
fi
if unlink "$file" 2>/dev/null; then
echo "Removed: $file"
return 0
else
echo "Error: Failed to remove '$file'"
return 1
fi
}
# Usage examples
safe_unlink "temp.txt"
safe_unlink "important.txt" "true"
File Monitoring and Cleanup
#!/bin/bash
# Monitor directory and remove old files
monitor_and_clean() {
local directory="$1"
local max_age="$2" # in minutes
local pattern="${3:-*}"
while true; do
find "$directory" -name "$pattern" -type f -mmin +$max_age -exec sh -c '
for file; do
echo "Removing old file: $file"
unlink "$file" 2>/dev/null && echo "Removed: $file"
done
' sh {} +
sleep 300 # Check every 5 minutes
done
}
# Start monitoring
monitor_and_clean "/tmp" 60 "*.tmp" &
Error Recovery
Robust File Removal
#!/bin/bash
# Robust file removal with error handling
robust_unlink() {
local file="$1"
local max_attempts="$2"
local attempt=1
while [ $attempt -le $max_attempts ]; do
if [ ! -f "$file" ]; then
echo "File '$file' does not exist"
return 0
fi
# Check if file is in use
if lsof "$file" >/dev/null 2>&1; then
echo "Attempt $attempt: File '$file' is in use, waiting..."
sleep $((attempt * 2))
else
if unlink "$file" 2>/dev/null; then
echo "Successfully removed: $file"
return 0
else
echo "Attempt $attempt: Failed to remove '$file'"
fi
fi
((attempt++))
done
echo "Failed to remove '$file' after $max_attempts attempts"
return 1
}
# Usage
robust_unlink "problematic_file.txt" 5
File System Check
#!/bin/bash
# Check filesystem before unlink operations
check_filesystem() {
local file="$1"
local dir=$(dirname "$file")
# Check if filesystem is read-only
if ! touch "$dir/.test_write" 2>/dev/null; then
echo "Error: Filesystem is read-only"
return 1
fi
unlink "$dir/.test_write" 2>/dev/null
# Check available space
local available=$(df "$dir" | awk 'NR==2 {print $4}')
if [ "$available" -lt 1024 ]; then # Less than 1KB
echo "Warning: Low disk space"
fi
return 0
}
# Safe unlink with filesystem check
safe_unlink_with_check() {
local file="$1"
if check_filesystem "$file"; then
unlink "$file"
else
echo "Cannot remove '$file': Filesystem issues detected"
return 1
fi
}
Integration and Automation
Shell Scripting Patterns
Conditional Unlinking
#!/bin/bash
# Conditional file removal
# Remove file only if it meets criteria
conditional_unlink() {
local file="$1"
local max_size="${2:-0}" # in bytes
local max_age="${3:-0}" # in days
[ ! -f "$file" ] && return 0
# Check file size
if [ "$max_size" -gt 0 ]; then
local size=$(stat -c%s "$file" 2>/dev/null || echo 0)
if [ "$size" -gt "$max_size" ]; then
echo "File '$file' is too large (${size} bytes)"
return 1
fi
fi
# Check file age
if [ "$max_age" -gt 0 ]; then
local age=$(find "$file" -mtime +$max_age -print)
[ -z "$age" ] && return 0
fi
unlink "$file" && echo "Removed: $file"
}
# Examples
conditional_unlink "temp.txt" 1048576 7 # Remove if >1MB and older than 7 days
Batch Operations
#!/bin/bash
# Batch unlink operations
# Read files from list and remove them
unlink_from_list() {
local file_list="$1"
local dry_run="${2:-false}"
while IFS= read -r -d '' file; do
if [ -f "$file" ]; then
if [ "$dry_run" = "true" ]; then
echo "Would remove: $file"
else
unlink "$file" && echo "Removed: $file"
fi
fi
done < <(tr '\n' '\0' < "$file_list")
}
# Create file list and remove
find /tmp -name "*.tmp" -print0 > temp_files.list
unlink_from_list "temp_files.list" "true" # Dry run
unlink_from_list "temp_files.list" # Actual removal
unlink temp_files.list
System Integration
Cron Job Integration
#!/bin/bash
# Cleanup script for cron jobs
# Place in: /etc/cron.daily/cleanup_temp_files
LOG_FILE="/var/log/cleanup.log"
TEMP_DIRS="/tmp /var/tmp"
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
# Cleanup function
cleanup_temp_files() {
local dir="$1"
local count=0
find "$dir" -maxdepth 1 -name "tmp.*" -type f -mtime +1 -exec sh -c '
file="$1"
if unlink "$file" 2>/dev/null; then
echo "$file"
fi
' sh {} \; | while read -r file; do
((count++))
log_message "Removed temporary file: $file"
done
return $count
}
# Main cleanup
total_removed=0
for dir in $TEMP_DIRS; do
if [ -d "$dir" ]; then
count=$(cleanup_temp_files "$dir")
total_removed=$((total_removed + count))
fi
done
log_message "Cleanup completed. Removed $total_removed files."
Service Integration
#!/bin/bash
# Service cleanup script
SERVICE_NAME="myapp"
PID_FILE="/var/run/$SERVICE_NAME.pid"
SOCKET_FILE="/var/run/$SERVICE_NAME.sock"
# Cleanup service files on service stop
cleanup_service_files() {
# Remove PID file if process is not running
if [ -f "$PID_FILE" ]; then
if ! kill -0 $(cat "$PID_FILE") 2>/dev/null; then
echo "Removing stale PID file"
unlink "$PID_FILE"
fi
fi
# Remove socket file if it exists
if [ -S "$SOCKET_FILE" ]; then
echo "Removing socket file"
unlink "$SOCKET_FILE"
fi
# Clean up temporary service files
find "/tmp/$SERVICE_NAME" -name "*.tmp" -type f -exec unlink {} \; 2>/dev/null
}
# Call this function when service stops
cleanup_service_files
Troubleshooting
Common Issues
Permission Problems
# Check file permissions
ls -l problematic_file.txt
# Check ownership
stat problematic_file.txt
# Try with sudo if necessary
sudo unlink protected_file.txt
# Change permissions first (if allowed)
chmod 644 file.txt
unlink file.txt
File in Use Issues
# Check what process is using the file
lsof +f -- /path/to/file.txt
# List open files for a specific process
lsof -p PID
# Find processes using files in a directory
lsof +D /path/to/directory
# Force close and remove (dangerous!)
fuser -k file.txt
unlink file.txt # May now work
Filesystem Issues
# Check filesystem status
df -h /path/to/filesystem
# Check if filesystem is mounted read-only
mount | grep "on /path/to/filesystem"
# Remount as read-write (if possible)
sudo mount -o remount,rw /path/to/filesystem
# Check filesystem integrity
sudo fsck /dev/sdXn
Symbolic Link Issues
# Check if it's a broken link
readlink symlink.txt
ls -l symlink.txt
# Remove broken symlink
unlink broken_symlink.txt
# Check link target before removing
if [ ! -e "$(readlink -f symlink.txt)" ]; then
echo "Removing broken symlink"
unlink symlink.txt
fi
Related Commands
rm- Remove files and directories (more powerful)ln- Create links between filesfind- Search for files and execute commandslsof- List open filesstat- Display file or filesystem statusls- List directory contentschmod- Change file permissionschown- Change file owner and group
Best Practices
- Use
rmfor most operations -unlinkis too limiting for general use - Check file existence before unlinking to avoid errors
- Verify permissions before attempting to remove files
- Use absolute paths when unlinking files in scripts
- Handle errors gracefully in automated scripts
- Consider using
find -exec unlinkfor batch operations - Test with dry runs before大规模删除操作
- Log removals for audit purposes in production environments
- Backup important files before removal operations
- Use proper quoting for filenames with special characters
Performance Tips
unlinkis faster thanrmfor single file removal- Use
find -exec unlink {} +for better performance with many files - Avoid shell loops for large numbers of files
- Batch operations are more efficient than individual calls
- Consider
rm -ffor automated scripts where errors are acceptable - Use
xargs unlinkfor very large file lists - Minimize filesystem checks in performance-critical code
- Process files by directory to improve filesystem cache locality
The unlink command is a simple, low-level tool for removing single files. While it lacks the features and safety mechanisms of rm, its simplicity makes it useful in specific scenarios like scripts, system programming, and when you need precise control over file removal operations. Understanding its behavior with links, permissions, and filesystem operations is essential for safe and effective use.