/bin/sh should set SHELL to /bin/sh

2017-07-13 Thread John Reiser

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-redhat-linux-gnu' -DCONF_VENDOR='redhat' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib  -D_GNU_SOURCE -DRECYCLES_PIDS 
-DDEFAULT_PATH_VALUE='/usr/local/bin:/usr/bin'  -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic

uname output: Linux f25e64.local 4.11.7-200.fc25.x86_64 #1 SMP Mon Jun 26 
15:58:22 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-redhat-linux-gnu

Bash Version: 4.3
Patch Level: 43
Release Status: release

Description:
When invoked as /bin/sh with SHELL unset, then bash should set SHELL
to /bin/sh, not to the login shell for the current user.
The current behavior can lead to surprises when descendants of /bin/sh
invoke $SHELL.  There is even a reasonable argument that /bin/sh
_always_ should set SHELL=/bin/sh, even (and especially) overriding
an existing SHELL=/bin/bash.  This would agree with the manual page:
"SHELL: The full pathname to the shell is kept in this environment 
variable."

If it's not going to change, then please emphasize the current behavior
on the manual page:  "SHELL: ... If it is not set when the  shell 
starts,
bash assigns to it the full pathname of the current user's login shell,
even if the result is SHELL=/bin/bash but the current shell was invoked
as /bin/sh."

Repeat-By:
# Verify that /bin/sh is a link to bash.
$ ls -l /bin/sh
lrwxrwxrwx. 1 root root 4 Sep 30  2016 /bin/sh -> bash

# Remove SHELL from the environment, invoke /bin/sh,
# ask for the new value of SHELL.
# Note the single quotes to prevent expansion before invoking /bin/sh.
$ env --unset=SHELL /bin/sh -c 'echo $SHELL'
/bin/bash

# Be pedantic: verify the comments above
$ strace -e trace=execve -v -s 100 env --unset=SHELL /bin/sh -c 'echo 
$SHELL'
execve("/usr/bin/env", ["env", "--unset=SHELL", "/bin/sh", "-c", "echo $SHELL"], 
[..., "SHELL=/bin/bash", ...]
execve("/bin/sh", ["/bin/sh", "-c", "echo $SHELL"], [..., /* no SHELL= 
*/, ...]

Fix:
Special case the setting of SHELL when the current shell
was invoked as /bin/sh.

--



Re: Debugging memory usage

2013-06-24 Thread John Reiser
 I took a look and saw the bash process consuming as much as 3+ GB of 
 memory.  I'm not doing anything where I'd expect to be consuming that 
 much memory.

As a workaround, try using ulimit -v to restrict the virtual memory
space of the shell itself.  (For invoking some child processes, it may
be necessary to use an intermediate shell which raises the limit before
exec-ing the child.)  It is not uncommon for a process (not just bash)
to allocate until refused, and only then think about free()ing or
collecting garbage.

-- 














Re: Obsolete SIGRTMAX-n signal names

2013-05-29 Thread John Reiser
On 05/29/2013 01:35 AM, Harald Hoyer wrote:
 On 04/24/2013 05:26 PM, Chet Ramey wrote:
 On 4/23/13 2:05 AM, Harald Hoyer wrote:
 As reported in http://savannah.gnu.org/patch/?8025 , I would like to see the
 SIGRTMAX-n signal names disappear.

 Signals should never ever be addressed with SIGRTMAX-n. Signals should 
 always be
 addressed with SIGRTMIN+n.

 I'll take a look at this, but that's a pretty strong statement to make from
 something that appears in one Linux man page.  I can't find any shell in my
 quick testing that behaves as you propose.  Is there any other reason to do
 this?

 Chet


 
 Any progress, comments?

Comment: In practice SIGRTMIN is a very stable value.  For each architecture
SIGRTMIN is chosen at the time of the original port, and after that SIGRTMIN
never will change, although in theory it could.  The value of SIGRTMAX
is less stable because it changes whenever _NSIG changes.  _NSIG has changed
from 32 to 64, and in some cases has reverted to 32 in order to save 4 bytes
[or 4*sizeof(void *)] in various places, and to make code smaller and simpler
[because (32/8)==sizeof(unsigned int)].

-- 




Re: How to match regex in bash? (any character)

2011-09-26 Thread John Reiser
Peng Yu wrote:
 I know that I should use =~ to match regex (bash version 4).
 
 However, the man page is not very clear. I don't find how to match
 (matching any single character). For example, the following regex
 doesn't match txt. Does anybody know how to match any character
 (should be '.' in perl) in bash.
 
 [[ $1 =~ xxx.txt ]]

The manual page for bash says that the rules of regex(3) apply:

  An additional binary operator,  =~,  is  available,  with  the  
same
  precedence  as  == and !=.  When it is used, the string to the 
right
  of the operator is considered an  extended  regular  expression  
and
  matched  accordingly (as in regex(3)).  The return value is 0 if 
the
  string matches the pattern, and 1 otherwise.
and also:
   Any part of the pattern may be quoted to force it to be matched 
as a
  string.

Thus in the expression   [[ $1 =~ xxx.txt ]]   the fact that the pattern
is quoted [here the whole pattern appears within double quotes] has turned the
dot '.' into a plain literal character, instead of a meta-character which 
matches
any single character.

The usual method of avoiding quotes in the pattern is to omit them:
  [[ $1 =~ xxx.txt ]]   # the dot '.' in the pattern is a 
meta-character
or to use a variable:
  pattern=xxx.txt   # a 7-character string
  [[ $1 =~ $pattern ]]   # the dot '.' in $pattern is a 
meta-character
Example: using all literals in an instance of bash:
   $ [[ txt =~ xxx.txt ]]  echo true
   true
   $

Also notice that quotes are not needed around the left-hand side  $1 :
   Word 
splitā€
  ting and pathname expansion are not performed on the  words  
between
  the  [[  and  ]] ...

Thus there is no need to use quotation marks to suppress word splitting
inside double brackets [[ ... ]].

-- 



Re: How to input ^J?

2010-07-18 Thread John Reiser
 Lastly since ^J is a newline you can generate one with echo \n.

That does not work in bash-4.x.  Firstly, by default the bash builtin
'echo' supplies a trailing newline.  Secondly, backslash translation
requires the option -e.

$ echo \n
\n
$ echo \n | od -c
000   \   n  \n
003
$

What does work is either of these:

$ echo '' | od -c
000  \n
001
$ echo -e -n '\n' | od -c
000  \n
001
$

-- 



Re: Set of characters that are treated specially between a pair of double quotes?

2010-07-11 Thread John Reiser
 Could anybody let me know the complete set of characters that need to
 be escaped (prepend with backslash) between a pair of double quotes if
 I really want to print the character?

RTFM.  In particular, the manual page (man bash) has a succinct section
entitled QUOTING.

-- 



Re: How to input tab in command line?

2010-07-10 Thread John Reiser
 I have command completion in my bash command. But I need to input tab
 in the command line. Is there a way to do so?

Quote the TAB with CtrlV.

$ echo ' ' | od -c   #  e c h o SPACE SQUO CtrlV TAB SQUO
000  \t  \n
002
$ echo '' | od -c # e c h o SPACE SQUO TAB SQUO
000  \n
001
$

-- 



Re: A note for read builtin

2010-06-18 Thread John Reiser
On 06/18/2010 07:05 AM, Dr. Werner Fink wrote:
 Just a remark about the sub shell usage in bash in comparision to
 ksh.  Let's try:
 
 strace -f -o bash.strace bash -c 'echo a b | read a b'
  grep -E 'execve|clone|write\(1|read\(0' bash.strace
  [snip]
 
 and now the same with the Korn shell
 
 strace -f -o ksh.strace ksh -c 'echo a b | read a b'
  grep -E 'execve|clone|write\(1|read\(0' ksh.strace | sed 's/^//'
  [snip]
 
 as now is visible the last command in the pipe sequence done
 in the bash is a real sub process whereas in the ksh it is not.
 
 The question rises: Why does the bash require a sub peocess/shell
 for the final command of a pipe sequence.

Running   strace -f -o ksh.strace ksh -c 'echo a b | cat'
shows that ksh requires a subprocess/shell for the 'cat'
which is the final command in _that_ pipe sequence.

Apparently ksh knows when the final command in a pipe sequence
is a shell builtin, then omits the subprocess in that case.

Could bash's $PIPE_STATUS[] or related issues about control,
environment, and history (trap, etc.) be relevant here?

-- 



Re: [bash-bug] Can arithmetic evaluation trap more than just division by zero?

2010-04-06 Thread John Reiser

Program received signal SIGFPE, Arithmetic exception.
0x00462cd5 in exp2 () at expr.c:761
761 val1 /= val2;
(gdb) print val1
$1 = -9223372036854775808
(gdb) print val2
$2 = -1

which is strange.



Not at all. Overflow invokes undefined behaviour.



But why there is no overflow on 32bit system?


No *detected* overflow.  For instance, if computing (2 ** 63)
gives 0 (the low-order 32 bits of the true result) and
does not detect the overflow (or ignores the overflow,
either by intention or by bug), then there is no problem
with computing (0 / -1).

--




Re: Mixing exec redirection with explicit redirection, unexpected results

2009-12-08 Thread John Reiser

#!/bin/bash

 /tmp/foo
exec 1/tmp/foo

echo a
echo B/tmp/foo
echo c
echo D/tmp/foo
echo e
echo F/tmp/foo


That script creates two simultaneous writers of /tmp/foo
(one via the exec , another via each echo )
but does not provide any concurrency control.
Shame on the script; the results are undefined.
The only possible legitimate complaint _might_ be
that bash did not detect and warn about the user error.

The fix is to provide some concurrency control,
or not to create multiple simultaneous writers of the same file.
Because all output is going to the same file, then the simplest
solution is to omit all the appending /tmp/foo because
they are subsumed by the initial redirection exec /tmp/foo.

Perhaps concurrency control can be provided by using a fifo:

mkfifo /tmp/my_fifo
cp /tmp/my_fifo /tmp/foo# constantly drain the fifo

exec /tmp/my_fifo
echo a
echo B /tmp/my_fifo

etc.  However, this relies upon bash _not_ buffering
the first redirection, and that is not guaranteed.

Bottom line: avoid simultaneous writers of the same file.

--




Re: slight OT: shell-script programing style -- origins and change?

2009-10-25 Thread John Reiser

... the age old convention of using upper case names
for all their shell variables. ...


It reminds some programmers that a '$' is necessary for expansion.
It is somewhat like using all capitals for #define macros in C
(where the expansion is automatic, but still different from other
symbols that aren't macro names.)  Both of these are surreptitious
salves for not having the full LISP conventions for eval and quote.

--




Re: preventing pipe reader from existing on writer exiting

2009-09-30 Thread John Reiser

Ultimately I need to do I/O through a named pipe and I
need to be able to restart the writer without restarting the reader.


The reader of a fifo will not be terminated as long as there is
at least one writer to the fifo.  Therefore, create a second writer.
For example, to hold the fifo open for one hour:

 sleep 3600   /tmp/fifo  

The shell forks, then opens /tmp/fifo for writing.  The open() waits
until there is a reader.  Then the forked shell execs /bin/sleep,
which waits for 3600 seconds before exiting.  During that 3600
seconds the fifo is open for writing, so the system will not
terminate any reader of the fifo for at least that long.

--




Re: Bash does not read up the whole script which it is currently executing

2009-08-04 Thread John Reiser

On 08/04/2009 12:48 AM, fam...@icdsoft.com wrote:

First I would like to say that I'm not sure if this is a bug or a 
feature of Bash.
If it is a feature, please let me know how to turn it off; or better 
make it disabled by default...

The problem is that Bash does not read up the whole script which it is 
currently executing.
As a result of this, if we update the script file with a newer version 
while it is running, this may lead to unpredicted results.


It is an intended design feature that the shell reads only as much as necessary
to proceed at the moment.  This is required so that subprocesses can share the 
same
stdin as the shell.  Bytes for input to the shell alternate with bytes for input
to each subprocess that does not have redirection (or closure) specified for 
its stdin.

To avoid this feature, then use the -c parameter to specify the entire shell 
input
as a string on the command line:
bash -c $( filename)
Or, make a temporary unique copy of the file, then invoke the shell on the copy.

--




omit fork before last exec

2009-08-03 Thread John Reiser

Hi,

Would it be possible for bash to detect just-in-time the last subprocess
that it will execute, and then do only an 'execve' instead of a fork+execve?
This might save a lot of operating system overhead for process creation:
perhaps upto 10% over the course of a day, especially for most uses of 'make'.

It seems to me that this could work if there are no active traps
and if the shell's input can be re-positioned without penalty.
An active trap might get triggered by the supposed last subprocess;
then interpreting the body of the trap could invalidate the last subprocess
property.  If the shell's input cannot be repositioned (is not a regular
file or -c command line string; is a pipe, socket, fifo, character device,
etc.) then lookahead on the shell's input is problematic.  Lookahead
is necessary to determine the last subprocess property.  However, the
lookahead must be undone before exec so that semantics remain the same
for the case when the shell and a subprocess share the input stream.
Piping input into a shell often relies on alternating consumption of
the piped input by the shell and one or more subprocesses that have
un-redirected stdin.

Comments?

--