Re: Should this be this way?
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?
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
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?
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?
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
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
* 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?
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?
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
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