Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

corrupted input after size function (input that's not recorded by bash)

3 views
Skip to first unread message

Linda Walsh

unread,
Jun 13, 2013, 3:58:02 PM6/13/13
to bug-bash

I have a small function in my bashrc:

function showsize () {\
local s=$(stty size); local o="(${s% *}x${s#* })"; s="${#o}";\
echo -n $o; while ((s-- > 0));do echo -ne "\b"; done; \
}
export -f showsize
trap showsize SIGWINCH
---
That has the effect of showing me my current window size
when I resize it.

The odd thing is, if I use it while at a bash input prompt --
any command I type has the first word ignored.

so if I type:
> echo cmd

If 'cmd' is not a typo you can use command-not-found to lookup the package that
contains it, like this:
cnf cmd
---
But then I re-edit the line (in vi-mode, ESC-k, it shows me I typed
echo cmd -- and, indeed, if I hit return, it echo's the word 'cmd' w/no error.

So how can my showsize function be mangling the input in a way that
prevents proper execution, but isn't recorded by bash?

(this has been one of those things that's bothered me for years, but
never been important enough to even ask about... I thought I'd look at it
to fix it, but still don't see why it does what it does).

Any clues?



Greg Wooledge

unread,
Jun 13, 2013, 4:15:51 PM6/13/13
to Linda Walsh, bug-bash
On Thu, Jun 13, 2013 at 12:58:02PM -0700, Linda Walsh wrote:
> So how can my showsize function be mangling the input in a way that
> prevents proper execution, but isn't recorded by bash?

What makes you believe it's this function that's causing your problem,
and not something else, such as a PROMPT_COMMAND variable? Or some
command which is altering the terminal in some bizarre way?

Linda Walsh

unread,
Jun 13, 2013, 4:45:39 PM6/13/13
to Greg Wooledge, bug-bash
It only happens when I alter the window size and the window
size is printed out.

Linda Walsh

unread,
Jun 13, 2013, 5:09:39 PM6/13/13
to Greg Wooledge, bug-bash


Greg Wooledge wrote:
> On Thu, Jun 13, 2013 at 12:58:02PM -0700, Linda Walsh wrote:
>> So how can my showsize function be mangling the input in a way that
>> prevents proper execution, but isn't recorded by bash?
>
> What makes you believe it's this function that's causing your problem,
> and not something else, such as a PROMPT_COMMAND variable? Or some
> command which is altering the terminal in some bizarre way?
--------------

FWIW, my prompt is a bit complex, but it's worked for years, so I
sorta doubt it is the problem:

read _CRST < <(tput sgr0) #Reset
read _CRed < <(tput setaf 1) #Red
read _CBLD < <(tput bold) #Bold
declare _prompt_open="" _prompt_close="" _prompt=">"
declare _disp_port=${DISPLAY/[^:]*:/}
[[ $UID -eq 0 ]] && {
_prompt_open="$_CBLD$_CRed"
_prompt="#"
_prompt_close="$_CRST"
}
PS1='\['"$_prompt_open"'\]$(spwd "$PWD" )'"$_prompt"'\['"$_prompt_close"'\] ';

if [[ -n ${REMOTEHOST:-""} ]]; then
function titlebar { \
printf "\033]1;${USER}@${HOSTNAME}:%q\007" "$(spwd "$PWD")" ;\
}
export -f titlebar

PS1='\[$(titlebar)'"$_prompt_open"'\]${HOSTNAME}:$(spwd
"$PWD")'"$_prompt"'\['"$_prompt_close"'\] '
fi
====
Puts out shortened path on my prompt and on the window title bar.
The title bar thing is very handy when you have a bunch of windows minimized
and want to find a tty window that is in a particular directory...as I move
my mouse over the minimized windows, it shows me the title -- so I see the path
of each window..


#==============swd is defined in another file:

alias int=declare\ -i _e=echo _pf=printf exp=export ret=return
exp __dpf__='local -a PF=(
"/$1/$2/$3/../\${$[$#-1]}/\${$#}"
"/$1/$2/../\${$[$#-1]}/\${$#}"
"/$1/../\${$[$#-1]}/\${$#}"
"/$1/../\${$#}"
".../\${$#}"
"..." )'
function spwd () { \
(($#)) || { _e "spwd called with null arg"; return 1; }; \
int w=COLUMNS/2 ;\
( _pf -v _p "%s" "$1" ; export IFS=/ ;\
set $_p; shift; unset IFS ;\
t="${_p#${HOME%${USER}}}" ;\
int tl=${#t} ;\
if (($#<=6 && tl<w));then ((tl<=2)) && \
{ _e -En "${_p}";return 0; } ;\
else \
eval "$__dpf__" ;\
int i pfl=${#PF[*]} ;\
for ((i=0; i<pfl; ++i)); do eval \
"_pf -v _pa %s \"${PF[i]}\"" ;\
_p="$(eval "_pf %s \"$_pa\"")" ;\
((${#_p}<w)) && break; done ;\
fi ;\
_e -En "${_p#${HOME%${USER}}}" )
}
--------------

It's the way I might wish \w|\W to work in bash...

PF is my array of formats. __dpf__ is a string that will define the array
(since I can't export arrays n hashes, I export things to define them)

It adopts longer paths if the paths all fit in the space, but shorter ones
when the path doesn't.. I let take up to half the screen, which is
a fair amount, but if I'm buried that deep somewhere, clues are handy.

Chris F.A. Johnson

unread,
Jun 13, 2013, 5:38:32 PM6/13/13
to Linda Walsh, bug-bash
On Thu, 13 Jun 2013, Linda Walsh wrote:
> I have a small function in my bashrc:
>
> function showsize () {\
> local s=$(stty size); local o="(${s% *}x${s#* })"; s="${#o}";\
> echo -n $o; while ((s-- > 0));do echo -ne "\b"; done; \
> }
> export -f showsize
> trap showsize SIGWINCH
> ---
> That has the effect of showing me my current window size
> when I resize it.
>
> The odd thing is, if I use it while at a bash input prompt --
> any command I type has the first word ignored.
>
> so if I type:
>> echo cmd
>
> If 'cmd' is not a typo you can use command-not-found to lookup the package
> that contains it, like this:
> cnf cmd
> ---
> But then I re-edit the line (in vi-mode, ESC-k, it shows me I typed
> echo cmd -- and, indeed, if I hit return, it echo's the word 'cmd' w/no
> error.
>
> So how can my showsize function be mangling the input in a way that
> prevents proper execution, but isn't recorded by bash?
>
> (this has been one of those things that's bothered me for years, but
> never been important enough to even ask about... I thought I'd look at it
> to fix it, but still don't see why it does what it does).
>
> Any clues?

The baskspaces (\b) are erasing your input, not the function's
output.

--
Chris F.A. Johnson, <http://cfajohnson.com/>
Author:
Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)

Linda Walsh

unread,
Jun 13, 2013, 7:42:36 PM6/13/13
to Chris F.A. Johnson, bug-bash
---
The idea of the backspaces was to put the cursor back in the original
position -- not erase anything. They are sent to the same file
handle (STDOUT) as the terminal size info -- they aren't piped to STDIN.

Second problem with that theory, I resize the window and see
the output... THEN, I type a command and the first word is ignored.
They couldn't erase my typing before I typed it could they? I admit
to being a bit rusty on my temporal programming theory, but I don't recall
post-deletion of future data to be an issue if you are not, at least,
using quantum computing. ;-| 'Sides -- another problem with that...
when I re-edit the line, Bash has recorded the line as typed. with no
erasures of the 1st word being recorded. Hmmm.. now if Bash displayed
the re-edited line outside the normal timeframe, that could explain that
too... but um... I'm not convinced that that bash would be executing
outside my timeframe....(i.e. no way! I don't see it). ;-)



Dennis Williamson

unread,
Jun 13, 2013, 10:05:10 PM6/13/13
to Linda Walsh, bug-...@gnu.org
On Jun 13, 2013 4:09 PM, "Linda Walsh" <ba...@tlinx.org> wrote:
>
>
>
> Greg Wooledge wrote:
>>
>> On Thu, Jun 13, 2013 at 12:58:02PM -0700, Linda Walsh wrote:
>>>
>>> So how can my showsize function be mangling the input in a way that
>>> prevents proper execution, but isn't recorded by bash?
>>
>>
Why are you doing

read _CRST < <(tput sgr0)

instead of

_CRST=$(tput sgr0)

Linda Walsh

unread,
Jun 14, 2013, 1:42:13 AM6/14/13
to Dennis Williamson, bug-...@gnu.org


Dennis Williamson wrote:

>
> read _CRST < <(tput sgr0)
>
> instead of
>
> _CRST=$(tput sgr0)
----

Run both of them with trace turned on and you'll find out.
;-)

I used to have the 2nd one...got tired of
having my tracing change colors when it got to that...



Greg Wooledge

unread,
Jun 14, 2013, 8:18:05 AM6/14/13
to Linda Walsh, Chris F.A. Johnson, bug-bash
On Thu, Jun 13, 2013 at 04:42:36PM -0700, Linda Walsh wrote:
> Chris F.A. Johnson wrote:
> > The baskspaces (\b) are erasing your input, not the function's
> > output.

That's incorrect. A backspace character sent to a terminal device
moves the cursor (or does whatever else the terminal chooses to do
when it receives the character) but has no effect on the input buffer.

> Second problem with that theory, I resize the window and see
> the output... THEN, I type a command and the first word is ignored.

For what it's worth, I cannot reproduce this in a simple test. I opened
a new window, and then:

imadev:~$ showsize() { echo xyz; }; trap showsize SIGWINCH
imadev:~$

The function and trap have been defined. Then I resized the window,
and xyz (plus newline) appeared as expected. I typed "echo foo" and
pressed Enter, and got the expected result.

imadev:~$ xyz
echo foo
foo
imadev:~$

This makes me continue to suspect that the problem is being triggered by
something else in your setup (possibly multiple things working together).

You might try to reproduce the problem in a simpler setup, to see if you
can isolate what factors must be present for it to occur.

Dave Gibson

unread,
Jun 14, 2013, 9:08:08 AM6/14/13
to bug-...@gnu.org
Linda Walsh <ba...@tlinx.org> wrote:
>
> I have a small function in my bashrc:
>
> function showsize () {\
> local s=$(stty size); local o="(${s% *}x${s#* })"; s="${#o}";\
> echo -n $o; while ((s-- > 0));do echo -ne "\b"; done; \
> }
> export -f showsize
> trap showsize SIGWINCH
> ---
> That has the effect of showing me my current window size
> when I resize it.
>
> The odd thing is, if I use it while at a bash input prompt --
> any command I type has the first word ignored.

Ignored or executed as a separate command?

Using bash 4.2.45, "echo ls /" is treated as "echo ; ls /" although
as you've noticed the command appears in the history as-typed.

>
> so if I type:
>> echo cmd
>
> If 'cmd' is not a typo you can use command-not-found to lookup the
> package that contains it, like this:
> cnf cmd
> ---
> But then I re-edit the line (in vi-mode, ESC-k, it shows me I typed
> echo cmd -- and, indeed, if I hit return, it echo's the word 'cmd'
> w/no error.
>
> So how can my showsize function be mangling the input in a way that
> prevents proper execution, but isn't recorded by bash?

Trial and error suggests it's something to do with new-style command
substitution. Try backticks:

local s=`stty size`

>
> (this has been one of those things that's bothered me for years, but
> never been important enough to even ask about... I thought I'd look at it
> to fix it, but still don't see why it does what it does).
>
> Any clues?

showsize()
{
local o="(${LINES}x${COLUMNS})" ; local s="${o//?/\\b}" ; printf "$o$s"
}



Linda Walsh

unread,
Jun 14, 2013, 10:33:05 AM6/14/13
to Greg Wooledge, bug-bash


Greg Wooledge wrote:

> This makes me continue to suspect that the problem is being triggered by
> something else in your setup (possibly multiple things working together).
>
> You might try to reproduce the problem in a simpler setup, to see if you
> can isolate what factors must be present for it to occur.

Well, that's good input... Now I have to figure out how to break your setup
too, er, I mean, fix my setup ... ;-)

I'll definitely try it sans anything else and see what comes up.

Could ven be the term settings or some interaction with the term emulator
you use vs. mine.


Linda Walsh

unread,
Jun 17, 2013, 2:32:04 AM6/17/13
to bug-...@gnu.org, Chet Ramey


Dave Gibson wrote:
> Trial and error suggests it's something to do with new-style command
> substitution. Try backticks:
>
> local s=`stty size`
----
Yes... you are right. This works... while
local s=$(stty size) does not.

That's icky! I thought they were identical, they appear not
to be...umm

Chet??? Hello? Um... why are these not the same?

local s=`stty size`
local s=$(stty size)

the latter seems to eat a param or similar when used in a function
at an input prompt...now I wonder what other side effects "$()" has over "``"



> showsize()
> {
> local o="(${LINES}x${COLUMNS})" ; local s="${o//?/\\b}" ; printf "$o$s"
> }
---
Well ain't that sweet. I thought I tried that at one point, though,
and they weren't updating hmmm...proof's in the pudding, I suppose..


Chet Ramey

unread,
Jun 25, 2013, 3:27:00 PM6/25/13
to Linda Walsh, bug-bash, chet....@case.edu
On 6/13/13 3:58 PM, Linda Walsh wrote:
>
> I have a small function in my bashrc:
>
> function showsize () {\
> local s=$(stty size); local o="(${s% *}x${s#* })"; s="${#o}";\
> echo -n $o; while ((s-- > 0));do echo -ne "\b"; done; \
> }
> export -f showsize
> trap showsize SIGWINCH
> ---
> That has the effect of showing me my current window size
> when I resize it.
>
> The odd thing is, if I use it while at a bash input prompt --
> any command I type has the first word ignored.

I haven't looked closely at this yet, but I bet that bash-4.2 running the
trap immediately when the SIGWINCH is received is screwing up the parser
state. A quick test shows me that running this on an empty line, then
hitting return after resizing the terminal and before entering a new
command, does not result in any errors.

This won't work in bash-4.3, which runs traps at command boundaries to
avoid just this kind of corruption.

Chet


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

0 new messages