bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

$PS0 patch


From: Dan Stromberg
Subject: $PS0 patch
Date: Sat, 24 Oct 2015 19:00:28 -0700


I've created a small diff against tonight's bash master branch for displaying a (single!) prompt after reading a command but before executing said command.

It's kind of like trapping debug, but it doesn't output the prompt once for each subcommand in a pipeline - it's just once for the thing you typed.  Even the following echo's just once:

address@hidden:~/src/bash/src$ ./bash
address@hidden:~/src/bash/src$ export PS0='fred>
> '
address@hidden:~/src/bash/src$ pwd
fred>
/home/dstromberg/src/bash/src
address@hidden:~/src/bash/src$ echo 1; echo 2; echo 3
fred>
1
2
3
address@hidden:~/src/bash/src$

My hope is that it can be merged into bash master.  I didn't see a way of doing a pull request with savannah, and gmail was refusing to do an attachment, so I've shar'd the patch file and pasted it below..

Thanks for the cool software!

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.11.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `#!/bin/sh' line above, then type `sh FILE'.
#
lock_dir=_sh22239
# Made on 2015-10-24 18:51 PDT by <address@hidden>.
# Source directory was `/tmp'.
#
# Existing files will *not* be overwritten, unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#   2227 -rw-r--r-- ps0-diffs
#
MD5SUM=${MD5SUM-md5sum}
f=`${MD5SUM} --version | egrep '^md5sum .*(core|text)utils'`
test -n "${f}" && md5check=true || md5check=false
${md5check} || \
  echo 'Note: not verifying md5sums.  Consider installing GNU coreutils.'
if test "X$1" = "X-c"
then keep_file=''
else keep_file=true
fi
echo=echo
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=
locale_dir=
set_echo=false

for dir in $PATH
do
  if test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    case `$dir/gettext --version 2>&1 | sed 1q` in
      *GNU*) gettext_dir=$dir
      set_echo=true
      break ;;
    esac
  fi
done

if ${set_echo}
then
  set_echo=false
  for dir in $PATH
  do
    if test -f $dir/shar \
       && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
    then
      locale_dir=`$dir/shar --print-text-domain-dir`
      set_echo=true
      break
    fi
  done

  if ${set_echo}
  then
    TEXTDOMAINDIR=$locale_dir
    export TEXTDOMAINDIR
    TEXTDOMAIN=sharutils
    export TEXTDOMAIN
    echo="$gettext_dir/gettext -s"
  fi
fi
IFS="$save_IFS"
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null
then if (echo -n test; echo 1,2,3) | grep n >/dev/null
     then shar_n= shar_c='
'
     else shar_n=-n shar_c= ; fi
else shar_n= shar_c='\c' ; fi
f=shar-touch.$$
st1=200112312359.59
st2=123123592001.59
st2tr=123123592001.5 # old SysV 14-char limit
st3=1231235901

if touch -am -t ${st1} ${f} >/dev/null 2>&1 && \
   test ! -f ${st1} && test -f ${f}; then
  shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'

elif touch -am ${st2} ${f} >/dev/null 2>&1 && \
   test ! -f ${st2} && test ! -f ${st2tr} && test -f ${f}; then
  shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'

elif touch -am ${st3} ${f} >/dev/null 2>&1 && \
   test ! -f ${st3} && test -f ${f}; then
  shar_touch='touch -am $3$4$5$6$2 "$8"'

else
  shar_touch=:
  echo
  ${echo} 'WARNING: not restoring timestamps.  Consider getting and
installing GNU `touch'\'', distributed in GNU coreutils...'
  echo
fi
rm -f ${st1} ${st2} ${st2tr} ${st3} ${f}
#
if test ! -d ${lock_dir} ; then :
else ${echo} "lock directory ${lock_dir} exists"
     exit 1
fi
if mkdir ${lock_dir}
then ${echo} "x - created lock directory ${lock_dir}."
else ${echo} "x - failed to create lock directory ${lock_dir}."
     exit 1
fi
# ============= ps0-diffs ==============
if test -n "${keep_file}" && test -f 'ps0-diffs'
then
${echo} "x - SKIPPING ps0-diffs (file already exists)"
else
${echo} "x - extracting ps0-diffs (text)"
  sed 's/^X//' << 'SHAR_EOF' > 'ps0-diffs' &&
diff --git a/doc/bash.1 b/doc/bash.1
index ec41462..97e46b3 100644
--- a/doc/bash.1
+++ b/doc/bash.1
@@ -2294,6 +2294,13 @@ trailing directory components to retain when expanding the \fB\ew\fP and
X .B PROMPTING
X below).  Characters removed are replaced with an ellipsis.
X .TP
+.B PS0
+The value of this parameter is expanded (see
+.SM
+.B PROMPTING
+below) and presented after a command is read, but before the command is
+executed.  The default value is ``'' (the null string).
+.TP
X .B PS1
X The value of this parameter is expanded (see
X .SM
diff --git a/eval.c b/eval.c
index 1f65aac..9f103f0 100644
--- a/eval.c
+++ b/eval.c
@@ -53,6 +53,7 @@ extern int last_command_exit_value, stdin_redir;
X extern int need_here_doc;
X extern int current_command_number, current_command_line_count, line_number;
X extern int expand_aliases;
+extern char *ps0_prompt;
X
X #if defined (HAVE_POSIX_SIGNALS)
X extern sigset_t top_level_mask;
@@ -157,6 +158,20 @@ reader_loop ()
X
X             executing = 1;
X             stdin_redir = 0;
+
+             /* After reading a command, before executing it */
+             if (ps0_prompt)
+               {
+                 char *ps0_string;
+                 ps0_string = decode_prompt_string(ps0_prompt);
+                 fprintf(stderr, ps0_string);
+                 free(ps0_string);
+                 /* stderr is often line buffered, so we flush; some
+                    PS0 prompts will have a trailing newline, and
+                    some won't.  We flush for those that don't.  */
+                 fflush(stderr);
+               }
+
X             execute_command (current_command);
X
X           exec_done:
diff --git a/parse.y b/parse.y
index 9cf7be8..90c3064 100644
--- a/parse.y
+++ b/parse.y
@@ -230,7 +230,7 @@ char *primary_prompt = PPROMPT;
X char *secondary_prompt = SPROMPT;
X
X /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
-char *ps1_prompt, *ps2_prompt;
+char *ps0_prompt, *ps1_prompt, *ps2_prompt;
X
X /* Handle on the current prompt string.  Indirectly points through
X    ps1_ or ps2_prompt. */
@@ -5161,6 +5161,7 @@ prompt_again ()
X   if (interactive == 0 || expanding_alias ()) /* XXX */
X     return;
X
+  ps0_prompt = get_string_value ("PS0");
X   ps1_prompt = get_string_value ("PS1");
X   ps2_prompt = get_string_value ("PS2");
X
SHAR_EOF
  (set 20 15 10 24 18 38 07 'ps0-diffs'
   eval "${shar_touch}") && \
  chmod 0644 'ps0-diffs'
if test $? -ne 0
then ${echo} "restore of ps0-diffs failed"
fi
  if ${md5check}
  then (
       ${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'ps0-diffs': 'MD5 check failed'
       ) << \SHAR_EOF
bec797981104380abeb2463ff9dc7426  ps0-diffs
SHAR_EOF
  else
test `LC_ALL=C wc -c < 'ps0-diffs'` -ne 2227 && \
  ${echo} "restoration warning:  size of 'ps0-diffs' is not 2227"
  fi
fi
if rm -fr ${lock_dir}
then ${echo} "x - removed lock directory ${lock_dir}."
else ${echo} "x - failed to remove lock directory ${lock_dir}."
     exit 1
fi
exit 0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]