When working with SSH, you might want to automatically navigate to a specific directory upon login. This is particularly useful when you frequently access certain project directories on remote servers. The naive approach of using LocalCommand in ~/.ssh/config often fails with confusing errors.
The LocalCommand directive executes on your local machine before the SSH connection is established. This explains why you're getting "No such file or directory" errors - it's trying to change directories locally, not on the remote server.
# This won't work as expected
Host example.net
LocalCommand "cd web" # Executes locally!
Here are several effective ways to achieve automatic directory changing on SSH login:
1. Using Remote Command
Add this to your ~/.ssh/config:
Host example.net
RemoteCommand cd /path/to/your/directory && exec \$SHELL
RequestTTY force
2. Modifying Shell Startup Files
Edit the remote server's ~/.bashrc or ~/.bash_profile:
# For interactive SSH sessions
if [[ -n $SSH_CONNECTION ]]; then
cd /path/to/your/directory
fi
3. Using SSH ForcedCommand
For more control, create a wrapper script:
#!/bin/bash
cd /path/to/your/directory
exec bash -i
Then in ~/.ssh/config:
Host example.net
RemoteCommand /path/to/wrapper_script
RequestTTY force
For different directories based on connection source:
if [[ "$SSH_CLIENT" =~ "192.168.1.100" ]]; then
cd /projects/client_a
elif [[ "$SSH_CLIENT" =~ "10.0.0.5" ]]; then
cd /projects/client_b
fi
- Always use absolute paths for reliability
- Check file permissions on the remote directory
- Verify your shell startup files are actually being sourced
- Test with
ssh -vfor debugging connection issues
When attempting to automatically change directories upon SSH login, many developers first try using LocalCommand in their SSH config. However, this approach fails because:
Host example.com
LocalCommand "cd /path/to/directory"
The key reasons this doesn't work:
LocalCommandexecutes on the client machine, not the remote server- Even with absolute paths, you'll encounter permission or I/O errors
- The command executes in a separate shell that terminates immediately
The most reliable method is to configure the remote shell's initialization files:
# For Bash users:
echo "cd /path/to/your/directory" >> ~/.bashrc
# For Zsh users:
echo "cd /path/to/your/directory" >> ~/.zshrc
This approach works because:
- Shell initialization files are executed after login
- The directory change persists for the entire session
- Works consistently across different SSH clients
For more control, combine SSH command with shell config:
# In your ~/.ssh/config
Host myserver
HostName example.com
User myuser
RequestTTY yes
RemoteCommand bash --init-file <(echo "source ~/.bashrc; cd /path/to/directory")
Benefits of this hybrid approach:
- Doesn't modify existing shell configuration
- Allows per-connection directory specification
- Maintains all shell initialization features
When you need a one-time directory change:
ssh -t user@example.com "cd /path/to/directory && exec \$SHELL -l"
This command:
- Changes to the specified directory immediately
- Starts an interactive shell in that location
- Doesn't require any configuration changes
Create multiple SSH config entries for different directories:
Host project1
HostName example.com
User dev
RemoteCommand bash -c "cd /projects/webapp && exec bash -l"
Host project2
HostName example.com
User dev
RemoteCommand bash -c "cd /projects/api && exec bash -l"
Now you can simply use:
ssh project1 # Automatically goes to /projects/webapp
ssh project2 # Automatically goes to /projects/api
Permission Issues: Ensure the target directory exists and is accessible:
ssh user@host "test -d /path/to/directory || echo 'Directory missing'"
Interactive Shell Problems: If commands exit immediately, force TTY allocation:
ssh -t user@host "cd /path && exec \$SHELL"
Environment Variables: Preserve them during directory change:
ssh -t user@host "cd /path && env -i HOME=$HOME USER=$USER \$SHELL -l"