NetBSD-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Scripting for /bin/ksh
On 08/02, Chavdar Ivanov wrote:
> On Mon, 2 Aug 2021 at 14:16, Todd Gruhn <tgruhn2%gmail.com@localhost> wrote:
> >
> > Thanks for the code Matt.
> > I will try this.
> > By 'execute' I mean generate
> > ${cmd}
> > then execute/do whatever ${cmd} turns out to be.
>
> Depending on the contents of cmd, you might have to use
>
> eval ${cmd}
Yes, and there's the rub: the corner cases. To correctly build up
a command like this and execute it where spaces and other special
characters are parsed correctly, you have to shell-quote cmd before
passing it to eval. See the "Shell-quoting arbitrary strings" section
in:
https://www.etalabs.net/sh_tricks.html
For example, here's a test program that correctly constructs and
executes two commands, touch and ls, to create and list some
"interesting" test files:
----
#!/bin/ksh
set -e
# https://www.etalabs.net/sh_tricks.html
quote() {
printf %s\\n "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/"
}
# https://dwheeler.com/essays/filenames-in-shell.html
nl=$(printf '\nX')
nl=${nl%X}
f1='test_a space'
f2='test_b"double-quote'
f3="test_c'single-quote"
f4="test_d${nl}newline"
f5='test_e\backslash'
f1_quoted=$(quote "$f1")
f2_quoted=$(quote "$f2")
f3_quoted=$(quote "$f3")
f4_quoted=$(quote "$f4")
f5_quoted=$(quote "$f5")
cmd="touch $f1_quoted $f2_quoted $f3_quoted $f4_quoted $f5_quoted"
printf 'cmd: %s\n' "$cmd"
eval "$cmd"
cmd="ls -B1 $f1_quoted $f2_quoted $f3_quoted $f4_quoted $f5_quoted"
printf 'cmd: %s\n' "$cmd"
eval "$cmd"
----
Lewis
Home |
Main Index |
Thread Index |
Old Index