Re: RFC: turn off word splitting for vars but keep for read

2013-11-25 Thread Bob Proulx
Greg Wooledge wrote:
> Bob Proulx wrote:
> > Aleksey Midenkov wrote:
> > > rmcmd="$rmprog -f"
> > > 
> > > Because it will fail for files with spaces.
> > 
> > I am sure we disagree but I don't consider making rm program names
> > have spaces to be reasonable.  :-/
> > 
> > What would it be?  "remove command"?  I definitely would not consider
> > an executable named with spaces that way to be reasonable.
> 
> How about /mnt/c/Program Files/something/DEL.EXE?  The directory might
> contain spaces even if the command name itself does not.

That would be using a full hard coded path.  I think using full hard
coded paths is bad for yet different reasons.

Here in this context it might be argued that hard coding the path is
part of a specific host's customization.  But IMNHO it is always
better to set PATH in that case.  Because it is never just one
command.  It will almost always be several commands in an open ended
list of possibilities.  In which case you will need PATH set
appropriately.  Having a PATH with spaces in it won't cause a problem
in this context.  But in any case such host customizations are better
to occur in a sourced configuration file and not in a production
script itself.

As a matter of style I very rarly would set options with the program
name in a program name variable.  (RSYNC_RSH comes to mind.)  I would
more typically set a companion $program_args variable instead.  But
then expect word splitting to occur in that args variable.  So it is
still the same issue just moved to a slightly different location.

Bob



Re: RFC: turn off word splitting for vars but keep for read

2013-11-25 Thread Greg Wooledge
On Sun, Nov 24, 2013 at 08:41:46PM -0700, Bob Proulx wrote:
> Aleksey Midenkov wrote:
> > rmcmd="$rmprog -f"
> > 
> > Because it will fail for files with spaces.
> 
> I am sure we disagree but I don't consider making rm program names
> have spaces to be reasonable.  :-/
> 
> What would it be?  "remove command"?  I definitely would not consider
> an executable named with spaces that way to be reasonable.

How about /mnt/c/Program Files/something/DEL.EXE?  The directory might
contain spaces even if the command name itself does not.



Re: RFC: turn off word splitting for vars but keep for read

2013-11-24 Thread Bob Proulx
Aleksey Midenkov wrote:
> I would say, that this style generally is wrong:
> 
> rmprog=${RMPROG-rm}
> rmcmd="$rmprog -f"
> 
> Because it will fail for files with spaces.

I am sure we disagree but I don't consider making rm program names
have spaces to be reasonable.  :-/

What would it be?  "remove command"?  I definitely would not consider
an executable named with spaces that way to be reasonable.

Bob



Re: RFC: turn off word splitting for vars but keep for read

2013-11-22 Thread Peggy Russell
> ...
> $ IFS=""
> $ f() { echo $1; }; x="a b c"; f $x
> a b c
> 
> But, IFS influences `read`, which of course benefits from word
> splitting. In light of that conflict, I propose two possible
> solutions:
> 
> 1: shopt -s unsplit_vars
> 
> which will turn off word splitting for var expansion.
> 
> or 2: new IFS2 var that will override IFS for `read` (i.e. `read` will
> use IFS2 when IFS is unset).
> 

Could also do:

  IFS=$'\n\t' 

  echo "Checking..."; echo -n "$IFS"|hexdump

The IFS on the read could be considered script documentation for
the contents of the current file. Similar to awk's FS.

  while IFS=: read -re line; do : ; done  < file

Interesting read here, but pertains to splitting and filenames:
http://www.dwheeler.com/essays/filenames-in-shell.html
But could perhaps provide a supportive argument, maybe, for your suggestion
option #1. http://mywiki.wooledge.org/Quotes is helpful.

Peggy Russell





Re: RFC: turn off word splitting for vars but keep for read

2013-11-22 Thread Aleksey Midenkov
On Fri, Nov 22, 2013 at 11:21 PM, Pierre Gaston  wrote:
>
>
>
> On Fri, Nov 22, 2013 at 8:53 PM, Eric Blake  wrote:
>>
>> On 11/22/2013 10:36 AM, Aleksey Midenkov wrote:
>>
>> > But nevertheless, I still find my proposal usable (since word
>> > splitting for vars is unlikely to be usable in scripts).
>>
>> Scripts use word splitting on variables ALL the time.  For example, I
>> bet you have (multiple copies of) a script named install-sh somewhere on
>> your system.  It frequently uses word split variables, such as these
>> setup lines:
>>
>> rmprog=${RMPROG-rm}
>> ...
>> rmcmd="$rmprog -f"
>>
>> for use in constructs like this:
>>   $doit $rmcmd -f "$dst" 2>/dev/null ||
>>
>> Disabling word splitting for an interactive shell is one thing (and in
>> fact, zsh has done that in their default mode), but for scripting, you
>> would break LOTS of existing scripts if you changed the default behavior
>> of word splitting.
>>
>> --
>> Eric Blake   eblake redhat com+1-919-301-3266
>> Libvirt virtualization library http://libvirt.org
>>
> well, he proposes an option to turn on these behavior, not to change the
> default behaviour.
> I reckon something like shopt -s autoquote_expansions could be useful

Exactly. I need this option only for my scripts, not for all scripts.
shopt -s unsplit_vars will be shorter and more clear, IMHO.

I would say, that this style generally is wrong:

rmprog=${RMPROG-rm}
rmcmd="$rmprog -f"

Because it will fail for files with spaces. It is better (when don't
worry about portability and backward compatibility like in autotools)
to use array:

rmcmd=("$rmprog" -f)

and then: "${rmcmd[@])"

But, these pesky double quotes we need to put everywhere because of
word splitting.



Re: RFC: turn off word splitting for vars but keep for read

2013-11-22 Thread Pierre Gaston
On Fri, Nov 22, 2013 at 8:53 PM, Eric Blake  wrote:

> On 11/22/2013 10:36 AM, Aleksey Midenkov wrote:
>
> > But nevertheless, I still find my proposal usable (since word
> > splitting for vars is unlikely to be usable in scripts).
>
> Scripts use word splitting on variables ALL the time.  For example, I
> bet you have (multiple copies of) a script named install-sh somewhere on
> your system.  It frequently uses word split variables, such as these
> setup lines:
>
> rmprog=${RMPROG-rm}
> ...
> rmcmd="$rmprog -f"
>
> for use in constructs like this:
>   $doit $rmcmd -f "$dst" 2>/dev/null ||
>
> Disabling word splitting for an interactive shell is one thing (and in
> fact, zsh has done that in their default mode), but for scripting, you
> would break LOTS of existing scripts if you changed the default behavior
> of word splitting.
>
> --
> Eric Blake   eblake redhat com+1-919-301-3266
> Libvirt virtualization library http://libvirt.org
>
> well, he proposes an option to turn on these behavior, not to change the
default behaviour.
I reckon something like shopt -s autoquote_expansions could be useful


Re: RFC: turn off word splitting for vars but keep for read

2013-11-22 Thread Eduardo A . Bustamante López
> Yes, I know, I'd ever done alias for `read`:
> 
> IFS=""
> shopt -s expand_aliases
> alias read='IFS=" " read'
Why do you obfuscate your code with aliases? These just make
debugging issues with your code harder. Remembering to quote
variables and use a localized IFS for read is easier, than
introducing an incompatible behaviour that will just help to make the
confusion of shell scripting bigger.

When giving support, it's easier to tell people: «Just double quote
every parameter expansion when you're in doubt», than to list all the
possible cases where they should and shouldn't. With your proposal,
you're just adding a new variable to the mess...

> But nevertheless, I still find my proposal usable (since word
> splitting for vars is unlikely to be usable in scripts).
Word splitting *IS* being used actively in lots of shell scripts that
aim for POSIX compatibility (because it's the only way of
pseudo-emulating arrays), and even it's used (wrongly) in bash
scripts that do not aim to be compatible with the POSIX shell.

So, if the user puts your shopt in ~/.bashrc and happens to run a
script that relies on that... breakage.


Also, lazyness is not a justification. Shell scripts are written
once, but read and executed many times, so invest a little time into
quoting properly, instead of relying on a modified IFS and set -f. Or
use a language that doesn't have to be compatible with POSIX sh.

Quoting isn't that hard once you get used to it ;)

-- 
Eduardo Alan Bustamante López



Re: RFC: turn off word splitting for vars but keep for read

2013-11-22 Thread Eric Blake
On 11/22/2013 10:36 AM, Aleksey Midenkov wrote:

> But nevertheless, I still find my proposal usable (since word
> splitting for vars is unlikely to be usable in scripts).

Scripts use word splitting on variables ALL the time.  For example, I
bet you have (multiple copies of) a script named install-sh somewhere on
your system.  It frequently uses word split variables, such as these
setup lines:

rmprog=${RMPROG-rm}
...
rmcmd="$rmprog -f"

for use in constructs like this:
  $doit $rmcmd -f "$dst" 2>/dev/null ||

Disabling word splitting for an interactive shell is one thing (and in
fact, zsh has done that in their default mode), but for scripting, you
would break LOTS of existing scripts if you changed the default behavior
of word splitting.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: RFC: turn off word splitting for vars but keep for read

2013-11-22 Thread Aleksey Midenkov
On Fri, Nov 22, 2013 at 7:07 PM, Pierre Gaston  wrote:
>
>
>
> On Fri, Nov 22, 2013 at 8:00 AM, Aleksey Midenkov  wrote:
>>
>> Since word splitting in vars is used not more frequently than never,
>> protecting all vars in scripts with double quotes is quite unpleasant
>> thing. Therefore, I want exactly this behavior always to be in my
>> scripts:
>>
>> $ IFS=""
>> $ f() { echo $1; }; x="a b c"; f $x
>> a b c
>>
>> But, IFS influences `read`, which of course benefits from word
>> splitting. In light of that conflict, I propose two possible
>> solutions:
>>
>> 1: shopt -s unsplit_vars
>>
>> which will turn off word splitting for var expansion.
>>
>> or 2: new IFS2 var that will override IFS for `read` (i.e. `read` will
>> use IFS2 when IFS is unset).
>
>
> Your code is still not safe, you would need set -f to disable globing too.
>
> it's easy enough to set IFS locally for read, just set it in its environment
> like
> IFS=' ' read a b <<"hello world"
>

Yes, I know, I'd ever done alias for `read`:

IFS=""
shopt -s expand_aliases
alias read='IFS=" " read'

But nevertheless, I still find my proposal usable (since word
splitting for vars is unlikely to be usable in scripts).



Re: RFC: turn off word splitting for vars but keep for read

2013-11-22 Thread Greg Wooledge
On Fri, Nov 22, 2013 at 10:00:28AM +0400, Aleksey Midenkov wrote:
> 1: shopt -s unsplit_vars
> 
> which will turn off word splitting for var expansion.

Basically, you want zsh.



Re: RFC: turn off word splitting for vars but keep for read

2013-11-22 Thread Pierre Gaston
On Fri, Nov 22, 2013 at 8:00 AM, Aleksey Midenkov  wrote:

> Since word splitting in vars is used not more frequently than never,
> protecting all vars in scripts with double quotes is quite unpleasant
> thing. Therefore, I want exactly this behavior always to be in my
> scripts:
>
> $ IFS=""
> $ f() { echo $1; }; x="a b c"; f $x
> a b c
>
> But, IFS influences `read`, which of course benefits from word
> splitting. In light of that conflict, I propose two possible
> solutions:
>
> 1: shopt -s unsplit_vars
>
> which will turn off word splitting for var expansion.
>
> or 2: new IFS2 var that will override IFS for `read` (i.e. `read` will
> use IFS2 when IFS is unset).
>

Your code is still not safe, you would need set -f to disable globing too.

it's easy enough to set IFS locally for read, just set it in its
environment like
IFS=' ' read a b <<"hello world"


RFC: turn off word splitting for vars but keep for read

2013-11-22 Thread Aleksey Midenkov
Since word splitting in vars is used not more frequently than never,
protecting all vars in scripts with double quotes is quite unpleasant
thing. Therefore, I want exactly this behavior always to be in my
scripts:

$ IFS=""
$ f() { echo $1; }; x="a b c"; f $x
a b c

But, IFS influences `read`, which of course benefits from word
splitting. In light of that conflict, I propose two possible
solutions:

1: shopt -s unsplit_vars

which will turn off word splitting for var expansion.

or 2: new IFS2 var that will override IFS for `read` (i.e. `read` will
use IFS2 when IFS is unset).