-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmn
executable file
·37 lines (31 loc) · 1.38 KB
/
mn
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/sh
# Move (`mv`) a file and then link (`ln`) to the new location from the old one. Based on
# Gilles' answer [here][1].
#
# [1]: https://unix.stackexchange.com/a/228166 "Move a file and replace it by a symlink"
# TODO: think more about the case where "$original" is a directory (maybe ending with
# slash); there may be problems (see <https://unix.stackexchange.com/q/253524>).
# See <https://mywiki.wooledge.org/BashFAQ/112>.
set -o nounset
[ "$#" -ne 2 ] && { echo "$0: wrong number of parameters" >&2; exit 1; }
original="$1" target="$2"
if [ -d "$target" ]; then
# When $2 is a directory, make sure `ln` will create a link to the moved file's new
# location inside that directory, not to the directory itself.
target="${target%/}/${original##*/}"
fi
mv -- "$original" "$target" || exit
case "${original%/}" in
*/*) # If the link may be created outside of the current directory...
case "$target" in
/*)
: ;;
*) # ...and the target path is not absolute, rewrite it to be absolute.
target="$(cd -- "$(dirname -- "$target")" && pwd)/${target##*/}"
esac
# If the link will be in the current directory and "$target" is a relative path, that
# relative path can be used as the link target directly since it is relative to the
# link's location.
esac
# TODO: move the file back if `ln` fails?
ln -sT -- "$target" "${original%/}"