-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathunwrap
executable file
·120 lines (106 loc) · 2.41 KB
/
unwrap
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env sh
# Run a command from a wrapper. The goal is to allow wrapper scripts located in
# $PATH to `exec` the "real" command without ending up in an infinite loop.
# Written by a tired ayekat in a train on a cold Wednesday night in November
# 2017.
set -e
set -u
RUNNAME="$(basename "$0")"
E_SUCCESS=0
E_USER=1
E_INTERNAL=2
E_COMMAND=127
which()
(
test $# -gt 0 || return 1
cmd="$1"; shift
if [ $# -gt 0 ]; then
ignored="$1"
shift
fi
test $# -eq 0 || return 1
IFS=:
for p in $PATH; do
cmdpath=$p/$cmd
if ! cmdpath_resolved=$(readlink -f "$cmdpath"); then
continue
fi
case "$ignored" in (*:$cmdpath:*|*:$cmdpath_resolved:*)
continue
esac
if [ -x "$cmdpath" ]; then
echo "$cmdpath"
return 0
fi
done
return 127
)
die()
{
retval=$(($1 + 0)); shift
if [ $retval -eq $E_INTERNAL ]; then
printf 'Internal error: ' >&2
fi
# shellcheck disable=SC2059
printf "$@" >&2
echo >&2
if [ $retval -eq $E_USER ]; then
printf 'Run with -h for more help\n' >&2
fi
exit $retval
}
help()
{
cat <<- EOF
Usage: $RUNNAME [OPTION...] COMMAND ...
Options:
-h Display this help message and exit.
-i FILEPATH In addition to ignoring the wrapper script location,
also ignore FILEPATH when searching for commands
(this option may be passed multiple times)
-t Test if the command could be unwrapped (exit with 1 if not)
-v Verbose: print path of unwrapped executable
EOF
}
# Options:
ignored=':'
test=false
verbose=false
while getopts :hi:tv opt; do
case "$opt" in
(h) help; exit $E_SUCCESS ;;
(i) ignored="$ignored$OPTARG:" ;;
(t) test=true ;;
(v) verbose=true ;;
(:) die $E_USER 'Missing argument for -%s' "$OPTARG" ;;
('?') die $E_USER 'Unknown option: -%s' "$OPTARG" ;;
(*) die $E_INTERNAL 'Unhandled option: -%s' "$OPTARG" ;;
esac
done
shift $((OPTIND - 1))
# Command:
test $# -gt 0 || die $E_USER 'Please specify a command'
cmd="$1"
shift
case "$cmd" in (*/*)
die $E_USER 'Please specify a command, not a path'
esac
# Get wrapper script path:
if ! wpath="$(which "$cmd" "$ignored")"; then
die $E_COMMAND 'command not found: %s' "$cmd"
fi
# Get "real" path:
if ! rpath="$(which "$cmd" ":$wpath$ignored")"; then
if $test; then
exit 1
fi
die $E_COMMAND 'wrapper script not unwrappable: %s' "$wpath"
fi
if $verbose; then
printf '%s\n' "$rpath"
fi
# Execute real executable:
if $test; then
exit 0
fi
exec "$rpath" "$@"