[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-bash] Assigning builtins behavior
From: |
Andy Chu |
Subject: |
Re: [Help-bash] Assigning builtins behavior |
Date: |
Sun, 7 Jan 2018 18:31:36 -0800 |
FWIW, here is another case where the shell parser has knowledge of the '='
character in assignments. It's not just an opaque string to a builtin
(e.g. as in 'env').
$ echo x-~andy
x-~andy
$ echo x=~andy
x=/home/andy
So although no assignments are made, merely changing the - character to =
causes tilde expansion to be triggered.
Dash has the opposite behavior, which IMO is very annoying and inconsistent:
x=~andy # YES tilde expansion in dash
readonly x=~andy # NO tilde expansion in dash
Come to think of it, the glob issue you point out with dash is one of the
things that led me to stop using it. It's a big difference and it showed
up in my scripts. In bash I believe you NEVER need to quote the RHS of
assignments. In dash you do! I'm pretty sure in bash, these pairs are
ALWAYS equivalent:
x=$a
x="$a"
local x=$a
local x="$a"
I investigated this awhile ago, and as far as I recall, ShellCheck knows
this rule. It tells you to put double quotes everywhere, except on the RHS
of assignments.
My test cases show the dash vs. bash/mksh (ksh derivative) difference:
http://www.oilshell.org/release/0.3.0/test/spec.wwz/tilde.html
More shell trivia:
http://www.oilshell.org/blog/
Andy
On Sun, Jan 7, 2018 at 1:10 PM, Quentin L'Hours <address@hidden>
wrote:
> Hi,
>
> I've always thought builtins could not have a custom parsing, however it
> seems that export/readonly/declare/local (all the builtins creating an
> assignment) are able to disable field splitting when an assignment takes
> place, why is that? I know a simple assignment disables field splitting,
> but after all that's because the grammar states it should, but doesn't
> POSIX requires all simple commands to have the same splitting behavior?
>
> bash$ foo=$(echo 1 bar=2)
> bash$ echo "$foo"
> 1 b=2
>
> This is logic, simple assignment doesn't triggers field splitting, that's
> the rule.
>
> bash$ set a=$foo
> bash$ echo "$1"
> a=1
>
> This is logic too, field splitting happens as expected
>
> bash$ readonly a=$foo
> bash$ echo "$a"
> 1 b=2
>
> Why? I know simple assignment doesn't split but I would have thought this
> should still follow the simple commands arguments expansion and thus should
> do 2 assignments. I mean builtins shouldn't be able to have their custom
> parsing, if they do then they should be classified as keywords (like [[
> ]]). What should be the POSIX way of doing things? Is this a bash extension?
>
> As a side note ksh has the same behavior, but dash follows what I thought
> would be the "normal" behavior:
>
> dash$ foo=$(echo 1 b=2)
> dash$ readonly a=$foo
> dash$ echo "$a"
> 1
> dash$ echo "$b"
> 2
>
> Thanks,
>
> --
> Quentin
>
>