Skip to content

Commit bd535fe

Browse files
committed
feat(link-to-bin): add configurable target directory and CLI options
- Allow specifying target bin directory via -t flag (default: ~/.local/bin) - Add usage/help output with -h option - Replace hardcoded DIR with TARGET_DIR variable - Improve formatting, quoting, and error handling - Preserve existing functionality for linking scripts and PATH setup
1 parent 3682c48 commit bd535fe

File tree

1 file changed

+81
-63
lines changed

1 file changed

+81
-63
lines changed

shell/general/link-to-bin.sh

100644100755
Lines changed: 81 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
#!/usr/bin/env bash
2-
# Script to link all the scripts to ~/.local/bin to be on PATH
3-
4-
# TODO: Maybe add ability to change target dir.
2+
# Script to link all the scripts to a target bin directory (default: ~/.local/bin) to be on PATH
53

64
# Only enable these shell behaviours if we're not being sourced
75
# Approach via: https://stackoverflow.com/a/28776166/8787985
8-
if ! (return 0 2>/dev/null); then
6+
if ! (return 0 2> /dev/null); then
97
# A better class of script...
108
set -o errexit # Exit on most errors (see the manual)
119
set -o nounset # Disallow expansion of unset variables
@@ -16,72 +14,92 @@ fi
1614
# Enable errtrace or the error trap handler will not work as expected
1715
set -o errtrace # Ensure the error trap handler is inherited
1816

19-
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
17+
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
18+
19+
TARGET_DIR="$HOME/.local/bin"
20+
21+
usage() {
22+
cat << EOF
23+
Usage: $(basename "$0") [-t target_dir]
24+
25+
-t DIR Target bin directory (default: $HOME/.local/bin)
26+
-h Show this help message
27+
EOF
28+
}
2029

21-
# pre check if ~/.local/bin exists and is in path or not and handle creation
22-
DIR="$HOME/.local/bin"
30+
while getopts ":t:h" opt; do
31+
case "$opt" in
32+
t) TARGET_DIR="$OPTARG" ;;
33+
h)
34+
usage
35+
exit 0
36+
;;
37+
*)
38+
usage
39+
exit 1
40+
;;
41+
esac
42+
done
43+
shift $((OPTIND - 1))
2344

24-
function handle_path() {
25-
DIR="$1"
26-
if [[ ":$PATH:" == *":${DIR}:"* ]]; then
27-
echo "${DIR} already in \$PATH, continuing."
28-
else
29-
echo "${DIR} not found in \$PATH"
30-
read -rp "Do you want to add it to your PATH? 'y' or 'n': " answer
31-
if [[ "$answer" == "y" ]]; then
32-
echo "export PATH=$DIR:\$PATH" >> "$HOME/.bashrc"
33-
echo "Run 'source ~/.bashrc' after this is done to make sure $DIR is in the PATH"
34-
elif [[ "$answer" == "n" ]]; then
35-
echo "There's no point in linking to $DIR if it's not in path..."
36-
echo "Run 'export $PATH=$DIR:$PATH' on the command line for temporary adding to PATH"
37-
else
38-
echo "Invalid input please enter 'y' or 'n'"
39-
exit 1
40-
fi
41-
fi
45+
handle_path() {
46+
local dir="$1"
47+
if [[ ":$PATH:" == *":${dir}:"* ]]; then
48+
echo "${dir} already in \$PATH, continuing."
49+
else
50+
echo "${dir} not found in \$PATH"
51+
read -rp "Do you want to add it to your PATH? 'y' or 'n': " answer
52+
if [[ "$answer" == "y" ]]; then
53+
echo "export PATH=${dir}:\$PATH" >> "$HOME/.bashrc"
54+
echo "Run 'source ~/.bashrc' after this is done to make sure ${dir} is in the PATH"
55+
elif [[ "$answer" == "n" ]]; then
56+
echo "There's no point in linking to ${dir} if it's not in path..."
57+
echo "Run 'export PATH=${dir}:\$PATH' on the command line for temporary adding to PATH"
58+
else
59+
echo "Invalid input please enter 'y' or 'n'"
60+
exit 1
61+
fi
62+
fi
4263
}
4364

44-
function link_scripts_to_bin() {
45-
# enable globbing things to make looping easier
46-
shopt -s globstar failglob nocaseglob
65+
link_scripts_to_bin() {
66+
# enable globbing things to make looping easier
67+
shopt -s globstar failglob nocaseglob
4768

48-
# loop through all files in the SCRIPT_DIR utilizing globstar
49-
for script in "${SCRIPT_DIR}"/** ; do
50-
# only operate on files that are executable and skip directories
51-
# TODO: Maybe in the future automatically make executable OR add to list then print at the end non executable files
52-
if [[ -x "$script" ]] && [[ -f "$script" ]] ; then
53-
# Remove extension from script so we can call it without adding extension
54-
filename="${DIR}/$(basename ${script%.*})"
55-
# link script to bin
56-
# TODO: investigate using ln -v
57-
ln -srn "${script}" "${filename}"
58-
59-
# print message depending on success or failure of symlinking
60-
if [[ $? -eq 0 ]]; then
61-
echo "Created symlink ${script} -> ${filename}"
62-
else
63-
echo "Something went wrong symlinking ${script} to ${filename}"
64-
fi
65-
fi
66-
done
67-
# unset because we're done
68-
shopt -u globstar failglob nocaseglob
69+
# loop through all files in the SCRIPT_DIR utilizing globstar
70+
for script in "${SCRIPT_DIR}"/**; do
71+
# only operate on files that are executable and skip directories
72+
# TODO: Maybe in the future automatically make executable OR add to list then print at the end non executable files
73+
if [[ -x "$script" ]] && [[ -f "$script" ]]; then
74+
# Remove extension from script so we can call it without adding extension
75+
filename="${TARGET_DIR}/$(basename "${script%.*}")"
76+
# link script to bin
77+
# TODO: investigate using ln -v
78+
if ln -srn "${script}" "${filename}"; then
79+
echo "Created symlink ${script} -> ${filename}"
80+
else
81+
echo "Something went wrong symlinking ${script} to ${filename}"
82+
fi
83+
fi
84+
done
85+
# unset because we're done
86+
shopt -u globstar failglob nocaseglob
6987
}
7088

7189
# if directory exists handle path stuff then symlink
72-
if [[ -d "$DIR" ]]; then
73-
handle_path "$DIR"
74-
link_scripts_to_bin
90+
if [[ -d "$TARGET_DIR" ]]; then
91+
handle_path "$TARGET_DIR"
92+
link_scripts_to_bin
7593
else
76-
# ask user if they want to create DIR, if yes handle path things and symlink
77-
# if not exit the script
78-
read -rp "Would you like to create ${DIR} ? ('y' or 'n'): " create
79-
if [[ "$create" == "y" ]]; then
80-
mkdir -pv "$DIR"
81-
handle_path "$DIR"
82-
link_scripts_to_bin
83-
elif [[ "$create" == "n" ]]; then
84-
echo "Exiting.."
85-
exit 1
86-
fi
94+
# ask user if they want to create TARGET_DIR, if yes handle path things and symlink
95+
# if not exit the script
96+
read -rp "Would you like to create ${TARGET_DIR} ? ('y' or 'n'): " create
97+
if [[ "$create" == "y" ]]; then
98+
mkdir -pv "$TARGET_DIR"
99+
handle_path "$TARGET_DIR"
100+
link_scripts_to_bin
101+
elif [[ "$create" == "n" ]]; then
102+
echo "Exiting.."
103+
exit 1
104+
fi
87105
fi

0 commit comments

Comments
 (0)