Linux Hidden Directory Conflict: Why mkdir Fails When ls Shows Empty Directory


4 views

When working with Linux systems, particularly when administering multiple user accounts, you might encounter this puzzling scenario:

root@server:~# cd /home/username
root@server:/home/username# ls
(no output)
root@server:/home/username# mkdir .ssh
mkdir: cannot create directory '.ssh': File exists

The root cause lies in how Linux handles hidden files and directories. Any file or directory starting with a dot (.) is considered hidden by default. The standard ls command won't display these unless specifically instructed to.

Here's what's actually happening in your case:

  • The .ssh directory exists but is hidden
  • Basic ls won't show hidden files
  • The system correctly prevents duplicate directory creation

To properly view ALL contents of a directory, including hidden files, use:

ls -a

Or for more detailed information:

ls -la

For the specific case of checking if .ssh exists:

ls -ld .ssh

When managing SSH keys or other configurations that use hidden directories, consider these patterns:

# Safe way to create .ssh directory if it doesn't exist
if [ ! -d ~/.ssh ]; then
    mkdir -p ~/.ssh
    chmod 700 ~/.ssh
fi

# Alternative using test command
[ -d ~/.ssh ] || mkdir -p ~/.ssh

When working across user accounts (especially as root), always verify and set appropriate permissions:

# Check existing permissions
ls -ld /home/username/.ssh

# Set correct permissions if needed
chown username:username /home/username/.ssh
chmod 700 /home/username/.ssh

For comprehensive directory analysis, combine multiple commands:

# Check for existence (silent)
[ -d .ssh ] && echo "Exists" || echo "Does not exist"

# View all files including hidden, with full details
ls -la | grep '^d'  # List only directories

This is a classic case of hidden files and directories in Linux systems. When you run ls without any flags, it doesn't show files/directories that begin with a dot (.). These are considered hidden items in Unix-like systems.


# What you see:
$ ls
(no output)

# What's actually there:
$ ls -a
.   ..   .ssh

The .ssh directory is commonly created automatically by SSH-related processes or other system utilities. Even though you can't see it with a regular ls, attempting to create it again triggers the "File exists" error because:

  • The directory exists but is hidden
  • Your user has insufficient permissions to view it
  • The directory might have unusual permissions set

To properly examine directory contents in Linux:


# Basic listing (hides dotfiles):
$ ls

# Show all files including hidden:
$ ls -a

# Long listing with all files:
$ ls -la

# Show directory contents with permissions:
$ ls -ld .ssh

If you need to work with the existing .ssh directory:


# Option 1: Access the existing directory
$ cd .ssh

# Option 2: Remove and recreate (be careful!)
$ rmdir .ssh
$ mkdir .ssh

# Option 3: Force creation (won't work if exists)
$ mkdir --ignore-existing .ssh

The issue might also stem from permission problems. Here's how to check and modify permissions:


# Check permissions:
$ ls -ld .ssh
drwx------ 2 user user 4096 Jun 10 10:00 .ssh

# Modify permissions if needed:
$ chmod 700 .ssh
$ chown user:user .ssh

For scripting scenarios, use this robust approach:


#!/bin/bash
SSH_DIR="/home/user/.ssh"

if [ ! -d "$SSH_DIR" ]; then
    mkdir -p "$SSH_DIR"
    chmod 700 "$SSH_DIR"
else
    echo "Directory $SSH_DIR already exists"
fi

Some additional commands that might help diagnose the situation:


# Check if directory exists:
$ [ -d .ssh ] && echo "Exists" || echo "Doesn't exist"

# Find all .ssh directories:
$ find /home -name .ssh -type d

# Get detailed inode information:
$ stat .ssh