How to Remove a Directory Named ^C (Control Character) in FreeBSD/Unix Systems


2 views

We've all made typos at the command line, but some can create particularly stubborn problems. Here's what happened when a simple mkdir command went wrong:

$ history
169 9:34    la /usr/local/etc/
170 9:35    sudo mkdir ^C
171 9:36    sudo mkdir /usr/local/etc/dnsmasq.d

The system created a directory literally named "^C" (the control character). When listing contents with ls, this appears as a question mark due to character encoding issues:

% ls -al
total 60
drwxr-xr-x  2 root   wheel    512 Jan 21 09:35 ?        <- this one
drwxr-xr-x  5 admin  wheel    512 Jan 21 16:24 .
[...]

We can confirm this is our problem child by checking inode numbers:

% ls -i
3611537 ?   3611534 bin

Method 1: Using Shell Escape Sequences

The most straightforward solution is to use escape sequences:

sudo rm -ri $'\\x03'/

Or alternatively:

sudo rm -ri $'\\cC'/

Method 2: Inode-based Removal

When filename approaches fail, use the inode number:

find . -inum 3611537 -exec sudo rm -rf {} \\;

Method 3: Wildcard Approach

For systems where the character appears as '?', try:

sudo rm -rf ./?

Be very careful with this approach as it will match any single-character filename.

To avoid similar issues:

  • Use mkdir -- "$dirname" to handle special characters
  • Consider using tab-completion for directory paths
  • Enable set -o noclobber in your shell

If these methods don't work, you might need to:

  1. Boot into single-user mode
  2. Use a live CD/filesystem repair tool
  3. Manually edit the directory structure using debugfs (for advanced users)

When working in Unix-like systems, we occasionally encounter files with problematic names containing control characters. In this case, a directory was accidentally created with the name ^C (ASCII code 3, ETX character) when the user meant to press Ctrl+C to cancel the command but instead created the directory.

$ ls -i
3611537 ?   3611534 bin

The main difficulties in removing such directories are:

  • The shell interprets ^C as the control character (Ctrl+C)
  • GUI file managers typically can't display or handle such characters
  • Standard commands like rm and rmdir fail with special characters

Method 1: Using Inode Number

Since ls -i shows the inode number (3611537 in our example), we can use it to remove the file:

find . -inum 3611537 -exec rm -rf {} \;

Or specifically for a directory:

find . -inum 3611537 -exec rmdir {} \;

Method 2: Shell Escape Sequences

In most shells, you can enter control characters using escape sequences:

rmdir $'\003'  # Where 003 is the octal code for Ctrl+C
rm -rf $'\x03' # Using hexadecimal representation

Method 3: Wildcard Matching

If the problematic name is the only one matching a pattern:

rm -rf *

Or more safely:

rm -rf ./?

Method 4: Using Perl

For complex cases, Perl can be helpful:

perl -e 'unlink("\cC")'        # For files
perl -e 'rmdir("\cC")'         # For directories

To avoid such situations in the future:

  1. Use set -o noclobber in bash to prevent accidental overwrites
  2. Consider using mkdir -i for interactive mode
  3. Implement shell aliases with confirmation prompts for destructive operations

For system administrators dealing with multiple such cases, consider:

# Find all files with control characters in their names
find /path -name $'*[\001-\037]*' -print0 | xargs -0 ls -ld

# Bulk rename utility (requires install)
pkg install rename
find . -name $'\003' -exec rename 's/\x03//g' {} +