Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Possible :q quoting bug
- X-seq: zsh-workers 44647
- From: Aryn Starr <whereislelouch@xxxxxxxxxx>
- To: Stephane Chazelas <stephane.chazelas@xxxxxxxxx>
- Subject: Re: Possible :q quoting bug
- Date: Fri, 9 Aug 2019 15:30:40 +0430
- Cc: zsh-workers@xxxxxxx
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=icloud.com; s=1a1hai; t=1565348446; bh=N4PnYjBUFi5uALws9wGRiP5SZOFYk/DdmYHeTJ2lGIE=; h=From:Message-Id:Content-Type:Subject:Date:To; b=tXe0GteN2Wh8lrWmAmdg6ePdX1Eek2nmKehLozb53oZ2sps/w/Ew9tb1LnTn6N4kN guALq4YhHECwqvulADWo58YTskvwwslKbjcP8zwAKTkLDr9QMZ2KIn1+g+zOMSei4f DCw661e0FR3xTFBesyIlT5gwPNV3gUHesRkBKKQudyejUegG4Y2llKarR4jYyP+ou0 SmNs5j6Pxse83mrnHinAbqM4xb/Fhe8gPZLT4UW4qcIw/LE7wFC3+oEw6yORS4YZY0 2nxCDlhJLBEB/1D65e7IJsGf2OM4gTsCZ0UvoBKMEMyi6tDcdaDQdrklJjGTktnGJ0 togzryNJmFo5g==
- In-reply-to: <20190808214818.fmfzcyqvzjtrmkpr@chaz.gmail.com>
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- List-unsubscribe: <mailto:zsh-workers-unsubscribe@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- References: <5E224043-AA93-4B39-94BB-6230A9A2737F@icloud.com> <20190808214818.fmfzcyqvzjtrmkpr@chaz.gmail.com>
Thanks! I suggest adding this little tidbit to the manpage.
I tested `”${(q@)@}” “${(q)@}” “${(qq@)@}”`. The only one to actually be idempotent (on my English locale at least) is `”${(q@)@}”. If you use `”${(qq@)@}”, you’ll lose aliases, which can be dangerous, when, e.g., you have aliases `rm` to `rm -i`. (Though generally I use aliases as little functions.)
> On Aug 9, 2019, at 2:18 AM, Stephane Chazelas <stephane.chazelas@xxxxxxxxx> wrote:
>
> 2019-08-08 20:36:00 +0430, Aryn Starr:
>> I expect this function to be idempotent on the command line:
>> ```
>> Function reveal() {
>> eval “${@:q}”
>> }
>> ```
>> But it’s not. It loses empty args.
>> I have written the following function to fix this ‘bug’:
>> ```
>> gquote () {
>> local i
>> for i in "$@"
>> do
>> test -z "$i" && print -rn "''" " " || print -rn -- "${i:q}" " "
>> done
>> }
>> ```
>
> You may want to use:
>
> reveal() eval "${(qq)@}"
>
> which is the zsh way to do it.
>
> $var:q is reminiscent of tcsh's $var:q though works differently
> (in tcsh, you do need cmd $var:q to pass the content of $var
> literally to cmd as tcsh has a completly fucked-up way of
> handling parameter expansions (hardly improved from the Thompson
> shell's simplistic parameter expansion from the early 70s).
>
> But like zsh's, tcsh's $var:q expands to nothing when $var is
> empty or a list of empty elements.
>
> Of the various ${(q)var}, ${(qq)var}, ${(qqq)var}, ${(qqqq)var}
> ${(q+)var}..., ${(qq)var} is the only one that is
> localisation-safe as it always using single quotes. The other
> ones (and also the quoting operators of other shells or of
> various printf %q) are generally not safe as they may quote some
> characters with \ (or use things like $'\n') and the encoding of
> \ is found in the encoding of some multi-byte characters in some
> locales.
>
> Note that mksh added a ${var@Q} which was later copied by bash.
>
> Initially, ${empty@Q} expanded to nothing (and it still does in
> bash), but that changed at some point in mksh where it now
> expands to ''. (possibly bash will follow).
>
> I'd agree zsh's documentation is misleading though as it
> currently says:
>
> q
> Quote the substituted words, escaping further substitutions. Works
> with history expansion and parameter expansion, though for
> parameters it is only useful if the resulting text is to be
> re-evaluated such as by eval.
>
>
> --
> Stephane
Messages sorted by:
Reverse Date,
Date,
Thread,
Author