Skip to content

Commit 7d166fe

Browse files
committed
refactor/robust(xpl/xpf): improve robustness 💪 ; check failure and reflect as exit code; improve portability(portableRelPath/portableReadLink)
NOTE: - use `printf` 💪 instead of `echo`; use `if-else` instead of `&&-||` - the `echo` option(e.g. -e -n) may effect correctness, `printf` is more robust 💪 - about `&&-||` see shell check: https://www.shellcheck.net/wiki/SC2015
1 parent 15047b0 commit 7d166fe

File tree

2 files changed

+54
-18
lines changed

2 files changed

+54
-18
lines changed

bin/xpf

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
22
# @Function
33
# Open file in file explorer, file is selected.
4-
# same as xpl --selected [file [file ...] ]
4+
# same as xpl --selected [file]...
55
#
66
# @Usage
77
# $ ./xpf file
@@ -10,6 +10,10 @@
1010
# @author Jerry Lee (oldratlee at gmail dot com)
1111
set -eEuo pipefail
1212

13+
################################################################################
14+
# util functions
15+
################################################################################
16+
1317
# How can I get the behavior of GNU's readlink -f on a Mac?
1418
# https://stackoverflow.com/questions/1055671
1519
portableReadLink() {
@@ -21,10 +25,16 @@ portableReadLink() {
2125
readlink -f "$file"
2226
;;
2327
Darwin*)
28+
local py_args=(-c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$file")
2429
if command -v greadlink >/dev/null; then
2530
greadlink -f "$file"
31+
elif command -v python3 >/dev/null; then
32+
python3 "${py_args[@]}"
33+
elif command -v python >/dev/null; then
34+
python "${py_args[@]}"
2635
else
27-
python -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$file"
36+
echo "fail to find command(greadlink/python3/python) for readlink!" >&2
37+
exit 1
2838
fi
2939
;;
3040
*)
@@ -34,5 +44,13 @@ portableReadLink() {
3444
esac
3545
}
3646

37-
BASE="$(dirname "$(portableReadLink "${BASH_SOURCE[0]}")")"
38-
source "$BASE/xpl" "$@"
47+
################################################################################
48+
# biz logic
49+
################################################################################
50+
51+
# DO NOT inline THIS_SCRIPT into BASE_DIR, because sub-shell:
52+
# BASE_DIR="$(dirname "$(portableReadLink "${BASH_SOURCE[0]}")")"
53+
THIS_SCRIPT="$(portableReadLink "${BASH_SOURCE[0]}")"
54+
BASE_DIR="$(dirname "$THIS_SCRIPT")"
55+
56+
source "$BASE_DIR/xpl" "$@"

bin/xpl

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,17 @@ PROG="$(basename "$0")"
3030
readonly PROG
3131
readonly PROG_VERSION='2.5.0-dev'
3232

33-
readonly nl=$'\n' # new line
33+
################################################################################
34+
# util functions
35+
################################################################################
3436

3537
usage() {
3638
local -r exit_code="${1:-0}"
3739
(($# > 0)) && shift
3840
# shellcheck disable=SC2015
3941
[ "$exit_code" != 0 ] && local -r out=/dev/stderr || local -r out=/dev/stdout
4042

41-
(($# > 0)) && echo "$*$nl" >$out
43+
(($# > 0)) && printf '%s\n\n' "$*" >$out
4244

4345
cat <<EOF
4446
Usage: ${PROG} [OPTION] [FILE]...
@@ -56,13 +58,10 @@ EOF
5658
}
5759

5860
progVersion() {
59-
echo "$PROG $PROG_VERSION"
61+
printf '%s\n' "$PROG $PROG_VERSION"
6062
exit
6163
}
6264

63-
# if program name is xpf, set option selected!
64-
[ "xpf" == "${PROG}" ] && selected=true
65-
6665
################################################################################
6766
# parse options
6867
################################################################################
@@ -96,10 +95,13 @@ while [ $# -gt 0 ]; do
9695
esac
9796
done
9897

98+
# if program name is xpf, set option selected!
99+
[ "xpf" == "${PROG}" ] && selected=true
100+
99101
readonly args selected
100102

101103
################################################################################
102-
# biz options
104+
# biz logic
103105
################################################################################
104106

105107
# open one file
@@ -109,33 +111,49 @@ openOneFile() {
109111
case "$(uname)" in
110112
Darwin*)
111113
[ -f "${file}" ] && slt=true
112-
open ${slt:+-R} "$file"
114+
if $slt; then
115+
open -R "$file"
116+
else
117+
open "$file"
118+
fi
113119
;;
114120
CYGWIN*)
115121
[ -f "${file}" ] && slt=true
116-
explorer ${slt:+/select,} "$(cygpath -w "${file}")"
122+
if $slt; then
123+
explorer /select, "$(cygpath -w "${file}")"
124+
else
125+
explorer "$(cygpath -w "${file}")"
126+
fi
117127
;;
118128
*)
119129
if [ -d "${file}" ]; then
120130
nautilus "$(dirname "${file}")"
121131
else
122-
if [ -z "${slt}" ]; then
123-
nautilus "$(dirname "${file}")"
124-
else
132+
if $slt; then
125133
nautilus "${file}"
134+
else
135+
nautilus "$(dirname "${file}")"
126136
fi
127137
fi
128138
;;
129139
esac
140+
141+
local selected_msg
142+
$slt && selected_msg='with selection'
143+
printf 'open %14s: %s\n' "$selected_msg" "$file"
130144
}
131145

132146
[ "${#args[@]}" == 0 ] && files=(.) || files=("${args[@]}")
147+
has_error=false
148+
133149
for file in "${files[@]}"; do
134150
[ ! -e "$file" ] && {
135-
echo "$file not existed!"
151+
printf '%s\n' "$file not existed!"
136152
continue
137153
}
138154

139155
openOneFile "$file"
140-
echo "$file opened${selected:+ with selection}!"
141156
done
157+
158+
# set exit status
159+
! $has_error

0 commit comments

Comments
 (0)