Pedro Gimeno's gists (pastes with history), each in an independent (orphan) branch

Pedro Gimeno a5c9434045 Use -T instead of -n to avoid surprises in rare cases; bashify 1 year ago
README.md a5c9434045 Use -T instead of -n to avoid surprises in rare cases; bashify 1 year ago
lnrel a5c9434045 Use -T instead of -n to avoid surprises in rare cases; bashify 1 year ago

README.md

lnrel - Create relative symlinks using tab expansion

This utility is designed for those who think that the interface of the ln system tool is uncomfortable to work with, in particular when creating relative symbolic links.

lnrel lets you use the tab expansion feature of the shell when creating a relative symbolic link, making the task much easier and less error prone.

Requirements: bash, basename, GNU ln

The first argument is always a path. This path must either start with ./ or contain the substring /./. Anything to the left of this substring is taken as the place where the link should be created, and anything to the right of it is taken as the content of the link. In case it starts with ./ the place where it will be created is the current directory.

The rest of arguments are optional. The second argument, if present, is the name to give to the link, when it differs from that of the target. Subsequent arguments will be passed to the ln command; for example -f may be necessary to overwrite existing files with the link.

For example, say you have a folder utilities and a folder bin in your current directory, and you want to create a relative symbolic link in bin called myutil which links to a file with the same name that resides in utilities. With ln you would have to do:

$ ln -s ../utilities/myutil bin/

With lnrel you can do it like this:

$ lnrel bin/./../utilities/myutil

The /./ in the path indicates: "here's where I want my symbolic link to be created". The rest of the path is the relative path to myutil from the directory where the symbolic link will be created; most importantly, you can use tab expansion to reach it. For example, you can type bin/./../ut<tab>my<tab> to autocomplete the path.

When lnrel executes, it will let you know what exact command it has passed to ln:

Creating link bin/myutil to point to ../utilities/myutil
+ ln -sT ../utilities/myutil bin/myutil

which is what we would have typed to create the link, but without the advantage of tab expansion. Note the use of the -T option of GNU ln, which forces the last argument to be interpreted as the link to create.

To create it with a different name, pass the new name as the second parameter:

$ lnrel bin/./../utilities/myutil myutil2
Creating link bin/myutil2 to point to ../utilities/myutil
+ ln -sT ../utilities/myutil bin/myutil2

To pass extra parameters to the ln command, append them after the second parameter. You can't omit the second parameter in that case, so repeat the target name if you want it to be the same as the source name.

$ lnrel bin/./../utilities/myutil3 myutil -f
Creating link bin/myutil to point to ../utilities/myutil3 with args "-f"
+ ln -sT -f ../utilities/myutil3 bin/myutil

Using absolute paths for destination is not a problem:

$ sudo lnrel /usr/local/lib/python/3.10/./../3.9/mylib
Creating link /usr/local/lib/python/3.10/mylib to point to ../3.9/mylib
+ ln -sT ../3.9/mylib /usr/local/lib/python/3.10/mylib

One disadvantage of this utility is that it doesn't allow creating multiple links at a time. Use ln for that; this is not what lnrel is designed for. It's designed to enable tab expansion to work for single links.