Re: Should this be this way?

2013-02-28 Thread Chet Ramey
On 2/27/13 11:05 PM, Linda Walsh wrote:
> 
> 
> Greg Wooledge wrote:
>>> How often, when at a terminal, do you type #!/bin/bash before every line?
>>
>> When I've put the contents into a file?  Every. single. time.
> ---
> Then when I press 'v' to edit the command line in a text editor --
> maybe 'bash' should insert such a line?  It's converted your command line
> into an editable file.  But it hasn't put the #!/bin/bash at the front.

This is a bad example.  The file that is the result of the vi-mode `v'
command is run as if it were sourced with `.'.  It's not run as if it
were a shell script.



-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: Should this be this way?

2013-02-28 Thread Bob Proulx
Chet Ramey wrote:
> Linda Walsh wrote:
> > Greg Wooledge wrote:
> >>> How often, when at a terminal, do you type #!/bin/bash before every line?
> >>
> >> When I've put the contents into a file?  Every. single. time.
> > ---
> > Then when I press 'v' to edit the command line in a text editor --
> > maybe 'bash' should insert such a line?  It's converted your command line
> > into an editable file.  But it hasn't put the #!/bin/bash at the front.
> 
> This is a bad example.  The file that is the result of the vi-mode `v'
> command is run as if it were sourced with `.'.  It's not run as if it
> were a shell script.

Ah!  There is the answer.  Don't run it as a script.  Always source
these files instead.  ". ./file"  When sourced they will run in the
context of the current bash shell and the behavior will be as
expected.

I say that somewhat tongue-in-cheek myself.  Because sourcing files
removes the abstraction barriers of a stacked child process and
actions there can persistently change the current shell.  Not good as
a general interface for random actions.  Normal scripts are better.

Bob

Who still remembers when if the exec(2) failed then the shell
examined the first character.  If it was a '#' then shell ran the file
through csh.  If ':' then through ksh.  If neither then sh.  This may
have been a local hack though.  Clearly the Berkeley #! hack is better.



Broken 'test -x' behaviour for euid=0 on Solaris

2013-02-28 Thread Jonathan Perkin
The implementation-defined behaviour of access() and faccessat() on Solaris is
as follows:

If any access permissions are to be checked, each will be
checked individually,  as  described  in  Intro(2).  If  the
process has appropriate privileges, an implementation  may
indicate  success for  X_OK  even  if  none of the execute file
permission bits are set.

As such, 'test -x' performed as root will return true even for files
which are not executable:

  bash-4.2# uname -srvm
  SunOS 5.11 joyent_20120126T071347Z i86pc
  bash-4.2# echo $BASH_VERSION 
  4.2.42(1)-release
  bash-4.2# touch /var/tmp/foo
  bash-4.2# ls -l /var/tmp/foo
  -rw-r--r--   1 root root   0 Feb 28 14:13 /var/tmp/foo
  bash-4.2# test -x /var/tmp/foo
  bash-4.2# echo $?
  0
  bash-4.2# /bin/test -x /var/tmp/foo
  bash-4.2# echo $?
  1
  bash-4.2# 

There is already handling for this chosen behaviour within sh_eaccess(), so it
is simply a matter of extending it for the faccessat() case, as implemented in
the patch below (against current git from git://git.sv.gnu.org/bash.git):

diff --git a/lib/sh/eaccess.c b/lib/sh/eaccess.c
index 534c526..453e328 100644
--- a/lib/sh/eaccess.c
+++ b/lib/sh/eaccess.c
@@ -206,7 +206,12 @@ sh_eaccess (path, mode)
 return (sh_stataccess (path, mode));
 
 #if defined (HAVE_FACCESSAT) && defined (AT_EACCESS)
-  return (faccessat (AT_FDCWD, path, mode, AT_EACCESS));
+  ret = faccessat (AT_FDCWD, path, mode, AT_EACCESS);
+#  if defined(SOLARIS)
+  if (ret == 0 && current_user.euid == 0 && mode == X_OK)
+return (sh_stataccess (path, mode));
+#  endif
+  return ret;
 #elif defined (HAVE_EACCESS)   /* FreeBSD */
   ret = eaccess (path, mode);  /* XXX -- not always correct for X_OK */
 #  if defined (__FreeBSD__)

Chances are high that 'defined (__FreeBSD__)' should be added to this test too,
but I do not have any FreeBSD machines on which to verify this, so I have not
added it for now.

I have verified this fix on SmartOS, an illumos distribution.  As far as I am
aware, the faccessat() implementation has not diverged between illumos and
Solaris 11, but again I do not have access to a Solaris 11 system to verify
this for certain.

Regards,

-- 
Jonathan Perkin  -  Joyent, Inc.  -  www.joyent.com



Re: Should this be this way?

2013-02-28 Thread Andreas Schwab
Bob Proulx  writes:

> I say that somewhat tongue-in-cheek myself.  Because sourcing files
> removes the abstraction barriers of a stacked child process and
> actions there can persistently change the current shell.  Not good as
> a general interface for random actions.  Normal scripts are better.

You can still put the sourcing in a subshell if you don't want
persistent changes.

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."



Re: Should this be this way?

2013-02-28 Thread Pierre Gaston
On Thu, Feb 28, 2013 at 7:09 PM, Andreas Schwab  wrote:
> Bob Proulx  writes:
>
>> I say that somewhat tongue-in-cheek myself.  Because sourcing files
>> removes the abstraction barriers of a stacked child process and
>> actions there can persistently change the current shell.  Not good as
>> a general interface for random actions.  Normal scripts are better.
>
> You can still put the sourcing in a subshell if you don't want
> persistent changes.
ehe, or just "bash script"



Re: Broken 'test -x' behaviour for euid=0 on Solaris

2013-02-28 Thread Chet Ramey
On 2/28/13 9:24 AM, Jonathan Perkin wrote:
> The implementation-defined behaviour of access() and faccessat() on Solaris is
> as follows:
> 
> If any access permissions are to be checked, each will be
> checked individually,  as  described  in  Intro(2).  If  the
> process has appropriate privileges, an implementation  may
> indicate  success for  X_OK  even  if  none of the execute file
> permission bits are set.
> 
> As such, 'test -x' performed as root will return true even for files
> which are not executable:
> 
>   bash-4.2# uname -srvm
>   SunOS 5.11 joyent_20120126T071347Z i86pc
>   bash-4.2# echo $BASH_VERSION 
>   4.2.42(1)-release
>   bash-4.2# touch /var/tmp/foo
>   bash-4.2# ls -l /var/tmp/foo
>   -rw-r--r--   1 root root   0 Feb 28 14:13 /var/tmp/foo
>   bash-4.2# test -x /var/tmp/foo
>   bash-4.2# echo $?
>   0
>   bash-4.2# /bin/test -x /var/tmp/foo
>   bash-4.2# echo $?
>   1
>   bash-4.2# 
> 
> There is already handling for this chosen behaviour within sh_eaccess(), so it
> is simply a matter of extending it for the faccessat() case, as implemented in
> the patch below (against current git from git://git.sv.gnu.org/bash.git):

Thanks for the report.  The code in the devel git branch looks like this:

#if (defined (HAVE_FACCESSAT) && defined (AT_EACCESS)) || defined
(HAVE_EACCESS)
#  if defined (HAVE_FACCESSAT) && defined (AT_EACCESS)
  ret = faccessat (AT_FDCWD, path, mode, AT_EACCESS);
#  else /* HAVE_EACCESS */  /* FreeBSD */
  ret = eaccess (path, mode);   /* XXX -- not always correct for X_OK */
#  endif/* HAVE_EACCESS */
#  if defined (__FreeBSD__) || defined (SOLARIS)
  if (ret == 0 && current_user.euid == 0 && mode == X_OK)
return (sh_stataccess (path, mode));
#  endif/* __FreeBSD__ || SOLARIS */
  return ret;
#elif defined (EFF_ONLY_OK) /* SVR4(?), SVR4.2 */
  return access (path, mode|EFF_ONLY_OK);
#else
  if (mode == F_OK)
return (sh_stataccess (path, mode));

It looks like I made that change some time ago.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



Re: Broken 'test -x' behaviour for euid=0 on Solaris

2013-02-28 Thread Jonathan Perkin
* On 2013-02-28 at 19:13 GMT, Chet Ramey wrote:

> On 2/28/13 9:24 AM, Jonathan Perkin wrote:
>
> > There is already handling for this chosen behaviour within sh_eaccess(), so 
> > it
> > is simply a matter of extending it for the faccessat() case, as implemented 
> > in
> > the patch below (against current git from git://git.sv.gnu.org/bash.git):
> 
> Thanks for the report.  The code in the devel git branch looks like this:

Ah, apologies, I didn't realise 'master' was the release branch, and
indeed the 'devel' branch works as expected.

Sorry for the noise,

-- 
Jonathan Perkin  -  Joyent, Inc.  -  www.joyent.com



Re: Should this be this way?

2013-02-28 Thread Sven Mascheck
On Thu, Feb 28, 2013 at 09:55:01AM -0700, Bob Proulx wrote:

> Who still remembers when if the exec(2) failed then the shell
> examined the first character.  If it was a '#' then shell ran the file
> through csh.  If ':' then through ksh.  If neither then sh.  This may
> have been a local hack though.  Clearly the Berkeley #! hack is better.

the other way round :)
# was the Berkeley hack implemented in both sh and csh.
#! was the Bell Labs hack, but the first systems to implement
this outside Bell Labs were running in Berkeley.

(I haven't heard of such a ksh hack, yet. Would like to hear more,
 off-list if you like)



Re: Should this be this way?

2013-02-28 Thread Linda Walsh


Chet Ramey wrote:
> On 2/27/13 11:05 PM, Linda Walsh wrote:
>>
>> Greg Wooledge wrote:
 How often, when at a terminal, do you type #!/bin/bash before every line?
>>> When I've put the contents into a file?  Every. single. time.
>> ---
>> Then when I press 'v' to edit the command line in a text editor --
>> maybe 'bash' should insert such a line?  It's converted your command line
>> into an editable file.  But it hasn't put the #!/bin/bash at the front.
> 
> This is a bad example.  The file that is the result of the vi-mode `v'
> command is run as if it were sourced with `.'.  It's not run as if it
> were a shell script.
===
It's not rocket science to think that you don't want to keep hopping
back and forth from the command line to a GUI editor, so a logical
progression would have many people saving the file into /tmp/xxx,
chmod +x /tmp/xxx; gvim /tmp/xxx ; ... and continue...

People are used to side-by-side development looking at source and running
in another window, so as soon as people start opening a cmd line in
an external editor, it's quite rational to assume that some percentage
of them will save the file and continue work as a normal workflow.

It isn't one I use every day, but may scripts start out as 1 liners that
grow and are saved into files.

If I save the script in a 'bin' directory, I add the header, but
if it's in /tmp, it's not the first thing I'm thinking about.





Re: More fun with IFS

2013-02-28 Thread Dan Douglas
On Wednesday, February 27, 2013 01:31:58 PM Thorsten Glaser wrote:
> Why whitespace? $IFS certainly contains none. And the usual
> insertion rules all specify the first character of $IFS and
> specify what to do if $IFS is empty or unset (which it isn’t
> in these examples).

Well, ok then. I'm just nitpicking here. I think this makes sense because it 
distinguishes between $@ and $* when assigning to a scalar, so that the end 
result of $@ is always space-separated, as spaces delimit words during command 
parsing. Your way would make more sense to me if this were the Bourne shell 
where IFS is in charge of both the initial argument splitting and field 
splitting. In this case though it seems strange to use IFS to represent 
separate words.

Consider for example if you ever implement "${@@Q}". Because of this behavior, 
the integrity of the result can only be guaranteed with a default IFS during 
assignment. This can be demonstrated with zsh which implements the same 
expansion (with different syntax) and uses the same assignment rules as mksh.

 $ zsh -s <<\EOF
emulate ksh
typeset -a cmd
cmd=(echo w:x y:z)
IFS=: x=${(q)cmd[@]} # Now we're in trouble
typeset -p x
unset -v IFS # Different problem whether or not we go back to default.
eval $x
EOF

typeset x=echo:w:x:y:z
zsh:1: command not found: echo:w:x:y:z

> Yeah, of course, it’s the only way to do some things… I personally
> usually abstract everything eval into little functions of their
> own and then just use those.
>

I agree that's an excellent strategy. :)

-- 
Dan Douglas