This tool is designed to tame the handling of ~/.ssh/config files.
It can be used to split the config file into multiple files in ~/.ssh/config.d, and generate new config files from a provided ssh command line example.
Usage: sshcfgtool [subcommand] [options]
Subcommands:
split Split SSH config into separate files
translate Translate SSH command to SSH config entry
join Join config.d files back into a single config
split flags:
-c, --config string Path to the SSH config file
-d, --config-dir string Path to the config.d directory (default ~/.ssh/config.d)
-n, --dry-run Print intentions but don't actually change any files
-f, --force Force overwriting existing files
join flags:
-d, --config-dir string Path to the config.d directory (default ~/.ssh/config.d)
-o, --output string Path to the output file (use '-' for stdout)
-f, --force Force overwriting an existing output file
translate flags (given before the ssh command):
-a, --alias string Override the alias name for Host
-c, --create Create a new config file for the host in the config.d directory
-d, --config-dir string Path to the config.d directory (with --create)
To split your existing ~/.ssh/config into separate files named {host}.conf located in ~/.ssh/config.d:
sshcfgtool splitThe existing ~/.ssh/config file will be backed up to ~/.ssh/config.backup and a new config file generated containing Include /home/perry/.ssh/config.d/*.conf.
Host patterns containing glob characters are written to safe file names with the glob characters replaced, prefixed with zz- so they sort (and apply) last — Host * becomes zz-star.conf, Host *.example.com becomes zz-star.example.com.conf. This ordering matters because ssh uses the first obtained value for each option, so wildcard defaults must come after host-specific blocks. Multi-pattern Host lines (Host foo bar) become foo_bar.conf.
You can check the effective configuration a host would get with ssh -G, e.g. ssh -G somehost | grep port.
To merge all *.conf files in the config.d directory back into a single file:
sshcfgtool join -o ~/.ssh/config.joinedUse -o - to print to stdout. An existing output file requires -f to overwrite.
To convert an ssh command line to a config file entry, write your usual command after the translate subcommand:
sshcfgtool translate ssh -i ~/.ssh/somekey -A -X -p 2222 user@hostname | tee ~/.ssh/config.d/hostname.confFor better or worse, the code for this project was primarily written with the guidance of OpenAI's ChatGPT (GPT-4). It will probably be a very normal thing in a few years. Both Go and Python implementations are available. The Go version is currently the most up-to-date and includes unit tests. However, the final decision on which version will be the primary implementation has not been made.
The Go code follows the standard Go project layout: the CLI entrypoint lives in cmd/sshcfgtool and the core logic in internal/sshconfig.
go test ./...go run ./cmd/sshcfgtoolgo build -o sshcfgtool ./cmd/sshcfgtoolgo install github.com/pansapiens/ssh-config-tool/cmd/sshcfgtool@latestDependencies are managed using Go modules, with dependencies already defined in go.mod.
You don't need to run the commands below, since go run and go build will fetch dependencies as required.
For reference this is how the module was initialized and dependencies were installed:
go mod init github.com/pansapiens/ssh-config-tool
go get github.com/pmezard/go-difflib/difflib
go get github.com/google/shlex