* < "$@" doesn't expand properly?
@ 2025-10-03 22:47 Marc Chantreux
2025-10-03 23:31 ` Lawrence Velázquez
0 siblings, 1 reply; 7+ messages in thread
From: Marc Chantreux @ 2025-10-03 22:47 UTC (permalink / raw)
To: Dash
[-- Attachment #1: Type: text/plain, Size: 727 bytes --]
hello everyone,
I wrote a simple "inplace" script to be able to
work with commands that have no -i options.
The simplest way to do it (I thought) was
#!/bin/sh
set -eux
< "$@" | sponge "$1"
so inplace counter awk '{$0+=2}1' would be expanded
as
< 'counter' 'awk' '{$0+=2}1' | sponge 'counter'
but there is an error message
./inplace: 3: cannot open counter awk {$0+=2}1: No such file
so it seems that the expansion leads to
< 'counter awk {$0+=2}1' | sponge 'counter'
is this an expected behavior?
regards
--
Marc Chantreux
Pôle CESAR (Calcul et services avancés à la recherche)
Université de Strasbourg
14 rue René Descartes,
BP 80010, 67084 STRASBOURG CEDEX
03.68.85.60.79
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: < "$@" doesn't expand properly?
2025-10-03 22:47 < "$@" doesn't expand properly? Marc Chantreux
@ 2025-10-03 23:31 ` Lawrence Velázquez
2025-10-04 6:55 ` Marc Chantreux
0 siblings, 1 reply; 7+ messages in thread
From: Lawrence Velázquez @ 2025-10-03 23:31 UTC (permalink / raw)
To: Marc Chantreux; +Cc: dash
On Fri, Oct 3, 2025, at 6:47 PM, Marc Chantreux wrote:
> The simplest way to do it (I thought) was
>
> #!/bin/sh
> set -eux
> < "$@" | sponge "$1"
>
> so inplace counter awk '{$0+=2}1' would be expanded
> as
>
> < 'counter' 'awk' '{$0+=2}1' | sponge 'counter'
>
>
> but there is an error message
>
> ./inplace: 3: cannot open counter awk {$0+=2}1: No such file
>
> so it seems that the expansion leads to
>
> < 'counter awk {$0+=2}1' | sponge 'counter'
>
> is this an expected behavior?
POSIX leaves this unspecified. Section 2.7 [1] says that field
splitting is not performed on the word following a redirection
operator, and section 2.5.2 [2] says that the expansion of "$@" is
unspecified in that context.
Almost no shell works the way you are expecting, except for zsh in
native mode (which I suspect is where you first tried this syntax):
% cat /tmp/x.sh
< "$@"
% ./bash /tmp/x.sh a b
/tmp/x.sh: line 1: "$@": ambiguous redirect
% dash /tmp/x.sh a b
/tmp/x.sh: 1: cannot open a b: No such file
% ksh /tmp/x.sh a b
/tmp/x.sh[1]: a b: cannot open [No such file or directory]
% mksh /tmp/x.sh a b
/tmp/x.sh[1]: can't open a b: No such file or directory
% oksh /tmp/x.sh a b
/tmp/x.sh[1]: cannot open a b: No such file or directory
% yash /tmp/x.sh a b
yash: redirection: cannot open file `a b': No such file or directory
% zsh /tmp/x.sh a b
/tmp/x.sh:1: no such file or directory: a
% zsh --emulate sh /tmp/x.sh a b
/tmp/x.sh:1: no such file or directory: a b
[1] https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/utilities/V3_chap02.html#tag_19_07
[2] https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/utilities/V3_chap02.html#tag_19_05_02
--
vq
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: < "$@" doesn't expand properly?
2025-10-03 23:31 ` Lawrence Velázquez
@ 2025-10-04 6:55 ` Marc Chantreux
2025-10-04 11:42 ` Harald van Dijk
2025-10-04 15:13 ` Lawrence Velázquez
0 siblings, 2 replies; 7+ messages in thread
From: Marc Chantreux @ 2025-10-04 6:55 UTC (permalink / raw)
To: Lawrence Velázquez; +Cc: dash
[-- Attachment #1: Type: text/plain, Size: 2494 bytes --]
Hi Lawrence,
> POSIX leaves this unspecified. Section 2.7 [1] says that field
> splitting is not performed on the word following a redirection
> operator, and section 2.5.2 [2] says that the expansion of "$@" is
> unspecified in that context.
wow ... thank you so much for digging this. this is the second time
this year where oppose POSIX standard against consistency and ease of
use.
I can understand why because most of the scripts I learned with were
postfixing the redirections so word splitting doesn't matter at this
point but prefixing the < is really a matter of easing the readability
and maintainance:
< A B | C | D > E
is much better for your brain than
B < A | C | D > E
> Almost no shell works the way you are expecting, except for zsh in
> native mode (which I suspect is where you first tried this syntax)
Not at all. Actually dash is not only the more lightweight shell I
know but also the one which behave as close as what I expect from a
POSIX shell so it became my first choice when it comes to scripting.
No shell behave the way I would like (for example, none but zsh
allow prefixed redirections to compound expressions) to but the closest
are by far rc, dash and zsh.
> % ./bash /tmp/x.sh a b
> % dash /tmp/x.sh a b
> % ksh /tmp/x.sh a b
> % mksh /tmp/x.sh a b
> % oksh /tmp/x.sh a b
> % yash /tmp/x.sh a b
> % zsh /tmp/x.sh a b
I see we have the same shells in the scope. I just dropped bash from my
radar because its competitor (heavy but feature oriented) is way better
so I keep telling people to use zsh instead.
when in comes to the ratio (needed_features / kb), dash is gold.
> [1] https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/utilities/V3_chap02.html#tag_19_07
> [2] https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/utilities/V3_chap02.html#tag_19_05_02
As the behavior is undefined, of course, I would like to propose to
behave the most helpful way when it makes sense because
* the other usecases are already doable:
* if the expected behavior is "$*", so use "$*"
* what's the point of A < "$@" ? use "$1" instead
* it's a matter of consistency to me. why "$@" can't behave as "$@" ?
Again, thank you so much for such a precise and useful answer.
regards.
--
Marc Chantreux
Pôle CESAR (Calcul et services avancés à la recherche)
Université de Strasbourg
14 rue René Descartes,
BP 80010, 67084 STRASBOURG CEDEX
03.68.85.60.79
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: < "$@" doesn't expand properly?
2025-10-04 6:55 ` Marc Chantreux
@ 2025-10-04 11:42 ` Harald van Dijk
2025-10-04 13:31 ` Marc Chantreux
2025-10-04 15:13 ` Lawrence Velázquez
1 sibling, 1 reply; 7+ messages in thread
From: Harald van Dijk @ 2025-10-04 11:42 UTC (permalink / raw)
To: Marc Chantreux, Lawrence Velázquez; +Cc: dash
Hi,
On 04/10/2025 07:55, Marc Chantreux wrote:
> * it's a matter of consistency to me. why "$@" can't behave as "$@" ?
The word that follows a redirection operator is one of the special
contexts where operations that split words into multiple fields are
disabled for it. Variable assignment is another. This is why
foo='multiple words'
bar=$foo
echo $foo > $bar
writes the string "multiple words" to a file named "multiple words". The
second line does not run a "words" command (as 'bar=multiple words'
would suggest), and the third line does not create a file called
"multiple" (as 'echo multiple words > multiple words' would suggest).
It is this principle that dash follows when it expands "$@" as "$*" in
these contexts. I agree with you that if users want that, they can just
write "$*" instead, but I do think that when users do write "$@" anyway,
treating it as "$*" is the least questionable interpretation.
Cheers,
Harald van Dijk
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: < "$@" doesn't expand properly?
2025-10-04 11:42 ` Harald van Dijk
@ 2025-10-04 13:31 ` Marc Chantreux
0 siblings, 0 replies; 7+ messages in thread
From: Marc Chantreux @ 2025-10-04 13:31 UTC (permalink / raw)
To: Harald van Dijk; +Cc: Lawrence Velázquez, dash
[-- Attachment #1: Type: text/plain, Size: 1859 bytes --]
On Sat, Oct 04, 2025 at 12:42:30PM +0100, Harald van Dijk wrote:
> On 04/10/2025 07:55, Marc Chantreux wrote:
> > * it's a matter of consistency to me. why "$@" can't behave as "$@" ?
> The word that follows a redirection operator is one of the special contexts
> where operations that split words into multiple fields are disabled for it.
> Variable assignment is another. This is why
>
> foo='multiple words'
> bar=$foo
> echo $foo > $bar
wow ... another thing I ignored after more than 25 years of shell
scripting.
"case $foo" is another example I discovered recently (on this mailing
list AFAIR). The person who answered me talked about a "scalar context".
> It is this principle that dash follows when it expands "$@" as "$*" in these
> contexts. I agree with you that if users want that, they can just write "$*"
> instead, but I do think that when users do write "$@" anyway, treating it as
> "$*" is the least questionable interpretation.
Well ... I see a lot of people who just recomends to quote (and even brace)
everything (so $foo becomes "${foo}" in their coding style) just because
they fear expansions. I try to explain that expansions are good and word
splitting is useful but you have to be carreful but the more we have
exceptions to a simples rules, the more people will try to avoid errors and
go on quoting, losing the benefits of expansions. They finally
claim that "we should rewrite in python instead because shell behavior
is hard to understand".
However un fully understand than when a behavior is still used,
implementors try to make it consistent. Thank you so much for your explainations.
regards.
--
Marc Chantreux
Pôle CESAR (Calcul et services avancés à la recherche)
Université de Strasbourg
14 rue René Descartes,
BP 80010, 67084 STRASBOURG CEDEX
03.68.85.60.79
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: < "$@" doesn't expand properly?
2025-10-04 6:55 ` Marc Chantreux
2025-10-04 11:42 ` Harald van Dijk
@ 2025-10-04 15:13 ` Lawrence Velázquez
2025-10-05 7:21 ` Marc Chantreux
1 sibling, 1 reply; 7+ messages in thread
From: Lawrence Velázquez @ 2025-10-04 15:13 UTC (permalink / raw)
To: Marc Chantreux; +Cc: dash
On Sat, Oct 4, 2025, at 2:55 AM, Marc Chantreux wrote:
> wow ... thank you so much for digging this. this is the second time
> this year where oppose POSIX standard against consistency and ease of
> use.
>
> I can understand why because most of the scripts I learned with were
> postfixing the redirections so word splitting doesn't matter at this
> point
Sure it does. Redirections can be infixed, so these are all valid:
<file cmd arg
cmd <file arg
cmd arg <file
Someone who agrees with your argument should logically expect this
to "work":
set file arg
cmd < "$@"
>> Almost no shell works the way you are expecting, except for zsh in
>> native mode (which I suspect is where you first tried this syntax)
>
> Not at all.
Ah, well. I guessed so because I know from the zsh mailing lists
that you're a big zsh fan.
> As the behavior is undefined, of course, I would like to propose to
> behave the most helpful way when it makes sense because
>
> * the other usecases are already doable:
> * if the expected behavior is "$*", so use "$*"
> * what's the point of A < "$@" ? use "$1" instead
> * it's a matter of consistency to me. why "$@" can't behave as "$@" ?
One could easily make the same "consistency" argument from the
perspective of the redirection operator. POSIX disallows this
expansion from producing multiple fields...
var='foo bar'
cmd < $var
...so why should this one produce multiple fields?
set foo bar
cmd < "$@"
In any case, the existing behavior conforms to POSIX and is far
more portable, so it is not likely to change.
--
vq
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: < "$@" doesn't expand properly?
2025-10-04 15:13 ` Lawrence Velázquez
@ 2025-10-05 7:21 ` Marc Chantreux
0 siblings, 0 replies; 7+ messages in thread
From: Marc Chantreux @ 2025-10-05 7:21 UTC (permalink / raw)
To: Lawrence Velázquez; +Cc: dash
[-- Attachment #1: Type: text/plain, Size: 3956 bytes --]
Hi Lawrence,
On Sat, Oct 04, 2025 at 11:13:51AM -0400, Lawrence Velázquez wrote:
> Sure it does. Redirections can be infixed, so these are all valid:
>
> <file cmd arg
my prefered one by far
> cmd arg <file
The one i kept using for years just because examples use it while isn't
now my most hated by far. a good demonstration about reading the man
pages even if you think you know the tool.
> cmd <file arg
> Someone who agrees with your argument should logically expect this
> to "work":
>
> set file arg
> cmd < "$@"
I have to admit I forgot this one because I considered it confusing and
useless but thanks to your example, I realize today is a convenient way to
place the data source in "$1" instead of the top of stack and that could
be useful in dash scripting because where is no simple/rubust way to get
this top (the equivalent of $argv[-1] in zsh). But as "$@" in not
expanded after <, this usecase is wasted as well.
fool() {
local source="$1"
echo "content of $source:"
cat < "$@"
}
fool mind -n
content of mind:
sh: 4: cannot open mind -n: No such file
> >> Almost no shell works the way you are expecting, except for zsh in
> >> native mode (which I suspect is where you first tried this syntax)
> > Not at all.
> Ah, well. I guessed so because I know from the zsh mailing lists
> that you're a big zsh fan.
I'm also fan of rc and long time user of mksh, I also used tcsh at the end
of the last millenium and tested any other ones (including exotic ones
like zoidberg and elvish).
I once (~ 10 years ago?) wrote an email to Tom Duff to thank him for rc
ask him why there was no advanced variable expansions in rc (like
${foo#bar}, ${foo?oops} and so on). He answered me that nobody were using
them back then. He also wrote something that has a deep impact of the way
I think about shell scripting:
«rc means "run commands" and should not do much more»
from this day, I started to bet on external commands much more than
shell internals and realized my scripts where faster and more reliable.
As I didn't need all the zsh features anyore (and rc is sadly too
unknown to be used when you want to share your scripts), dash became my
almost only shebang (also almost all my scripts are working in a bare
busybox chroot, including CGIs).
I keep using zsh for interactive stuff because there is no competitor
on this part of the game thanks to
* "alternate syntax" for control statements
* advanced features like extended globs, list filtering, filename modifiers
* incredible zle widgets
> > As the behavior is undefined, of course, I would like to propose to
> > behave the most helpful way when it makes sense because
> >
> > * the other usecases are already doable:
> > * if the expected behavior is "$*", so use "$*"
> > * what's the point of A < "$@" ? use "$1" instead
> > * it's a matter of consistency to me. why "$@" can't behave as "$@" ?
>
> One could easily make the same "consistency" argument from the
> perspective of the redirection operator. POSIX disallows this
> expansion from producing multiple fields...
>
> var='foo bar'
> cmd < $var
>
> ...so why should this one produce multiple fields?
> set foo bar
> cmd < "$@"
from the POSIX perspective, it indeed shouldn't.
> In any case, the existing behavior conforms to POSIX and is far
> more portable, so it is not likely to change.
That's what I learnt from you (again: thank you so much) and
made me so sad: consistency on POSIX compliance avoid consistency around
useful behaviors. On the other hand, I totally support the idea that at
least one shell must be POSIX compatible flaw by flaw.
there is no perfect shell in this world :)
regards
--
Marc Chantreux
Pôle CESAR (Calcul et services avancés à la recherche)
Université de Strasbourg
14 rue René Descartes,
BP 80010, 67084 STRASBOURG CEDEX
03.68.85.60.79
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-10-05 7:28 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-03 22:47 < "$@" doesn't expand properly? Marc Chantreux
2025-10-03 23:31 ` Lawrence Velázquez
2025-10-04 6:55 ` Marc Chantreux
2025-10-04 11:42 ` Harald van Dijk
2025-10-04 13:31 ` Marc Chantreux
2025-10-04 15:13 ` Lawrence Velázquez
2025-10-05 7:21 ` Marc Chantreux
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox