-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharg_save
50 lines (48 loc) · 1.58 KB
/
arg_save
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
#! .desc:
# Save with single-quote escape an argument into a variable
#! .params:
# <"$1"> - argument
# <$2> - variable name
#! .uses.var.replchar:
# [POSIX_COMPAT] $ - environment variable;
# forces the usage of parameter expansion; necessary for
# POSIX.1-2024 compliance
#! .uses.fn:
# <assert> ('-shell-name' '$2');
# Assert a string
# <replchar> ('\'' '\'\\\'\'' '$1');
# Replace a specific character with character(s) in a string
#! .rc:
# (0) success
# (*) error
#! .rc.fn:
# (assert) (255) bad input
# (replchar) (*) error
#.
arg_save() {
# Escape any single quotes in the argument ($1).
case "$1" in
*\'*)
replchar \' \'\\\'\' "$1" || return "$?" # -> $_str
set -- "$_str" "$2"
;;
esac
assert -shell-name "$2" || return 255
# The usage of `eval` here is safe. Assuming $1 is `"'\''abc` (we escape
# single quotes in $1 before they're passed to `eval`) and $2 is `a`:
#
# First expansion (current shell):
# `eval "$2=\"\$$2 '\$1'\""` -> `eval a="$a '$1'"` (lit.)
#
# Second expansion (`eval`); assuming the content of $a is `'b'`:
# `eval a="$a '$1'"` -> `a = 'b' '"'\''abc'` (illust. of meta expansion)
#
# Key points:
# - Due to the sophisticated escaping, single quotes from the first
# expansion carry their significance to the second expansion.
#
# For more information, refer to:
# > "POSIX.1-2024, Volume: Shell & Utilities, Section: Shell Command
# Language, Subsection: Quoting".
eval "$2=\"\$$2 '\$1'\""
}