Re: RFC: turn off word splitting for vars but keep for read
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
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
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
On Fri, Nov 22, 2013 at 8:00 AM, Aleksey Midenkov mide...@gmail.com 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
Re: RFC: turn off word splitting for vars but keep for read
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
On Fri, Nov 22, 2013 at 7:07 PM, Pierre Gaston pierre.gas...@gmail.com wrote: On Fri, Nov 22, 2013 at 8:00 AM, Aleksey Midenkov mide...@gmail.com 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
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
On Fri, Nov 22, 2013 at 8:53 PM, Eric Blake ebl...@redhat.com 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
On Fri, Nov 22, 2013 at 11:21 PM, Pierre Gaston pierre.gas...@gmail.com wrote: On Fri, Nov 22, 2013 at 8:53 PM, Eric Blake ebl...@redhat.com 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
... $ 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