lnk is an interactive wrapper around ln that helps you create symbolic and hard links safely.
It asks a small set of plain-English questions, explains the decision it makes, shows the equivalent shell command, and only proceeds after confirmation.
Creating links in Linux is simple, but the mental model is not:
- Hard links vs symbolic links
- Relative vs absolute paths
- What happens when things move or are deleted
- How links behave across filesystems
lnk makes those decisions explicit and teachable.
-
Interactive wizard by default
-
Explains why a link type was chosen
-
Shows the exact
lncommand before execution -
Safe handling of existing destinations (replace / backup)
-
Supports:
- Symbolic links (default)
- Hard links (explicit opt-in)
-
Works with standard Python (no dependencies)
Clone the repository and link the script into your PATH:
$ ./lnk ./lnk ~/bin/lnk
Detected source:
Input path: lnk
Absolute path: /home/user/dev/python/lnk/lnk
Kind: file
How should the new path behave?
Choose the behavior you want:
1. Like a reference or shortcut to the source [default]
2. Like a second name for the same file
> 1
Should this link keep working if this folder structure moves together? [Y/n]
Planned action
Source input: lnk
Source absolute: /home/user/dev/python/lnk/lnk
Link path: /home/user/bin/lnk
Link type: symlink
Path style: relative
Resolved target: /home/user/dev/python/lnk/lnk
Stored target: ../dev/python/lnk/lnk
Conflict action: none
Why these options were chosen:
- You chose reference-style behavior, so a symbolic link is appropriate.
- You said the paths may move together, so a relative symlink is appropriate.
Equivalent command:
ln -s ../dev/python/lnk/lnk /home/user/bin/lnk
Proceed with this action? [Y/n]Or non-interactively:
$ ./lnk --yes --replace ./lnk ~/bin/lnk
Detected source:
Input path: lnk
Absolute path: /home/user/dev/python/lnk/lnk
Kind: file
Planned action
Source input: lnk
Source absolute: /home/user/dev/python/lnk/lnk
Link path: /home/user/bin/lnk
Link type: symlink
Path style: absolute
Resolved target: /home/user/dev/python/lnk/lnk
Stored target: /home/user/dev/python/lnk/lnk
Conflict action: none
Why these options were chosen:
- Non-interactive mode defaults regular files to symbolic links.
- Non-interactive mode defaults symbolic links to absolute paths.
Equivalent command:
ln -s /home/user/dev/python/lnk/lnk /home/user/bin/lnk
Done.Make sure ~/bin is in your PATH.
lnk [--yes] [--dry-run] [--replace | --backup] from tofrom— source pathto— link path to create
lnk --help
usage: lnk [-h] [--yes] [--dry-run] [--replace] [--backup] from_path to_path
Create a symbolic link or hard link using an interactive wizard. By default, symlinks are preferred. Hard links are only created after explicit user choice in interactive mode.
positional arguments:
from_path Source path
to_path Link path to create
options:
-h, --help show this help message and exit
--yes Run non-interactively where possible. This auto-accepts defaults, but does not replace an existing destination unless --replace or --backup is also given.
--dry-run Show the planned action without changing the filesystem.
--replace Replace an existing destination without asking.
--backup Backup an existing destination before replacing it.lnk ~/dotfiles/nvim ~/.config/nvimlnk --dry-run ~/dotfiles/nvim ~/.config/nvimlnk --yes --replace ./lnk ~/bin/lnk- Directory → symbolic link
- File → symbolic link (default)
- Hard link only when explicitly chosen
- Relative → when paths may move together
- Absolute → otherwise (default in
--yesmode)
-
Never overwrites existing paths without confirmation
-
--yesdoes not overwrite unless combined with:--replace- or
--backup
-
Detects and skips already-correct links
-
No bind mounts
-
No special file support (devices, sockets, etc.)
-
Hard links:
- files only
- same filesystem only
- not supported for symlink sources
A file that points to another path.
- Works for files and directories
- Can cross filesystems
- Breaks if target moves
Another name for the same file (same inode).
- Files only
- Same filesystem only
- No “original” vs “link”
Requirements:
- Python 3.12+ (Ubuntu 24.04 default)
- No external dependencies
Run directly:
./lnk from toMIT