bash - Why do I sometimes get 'sh: $'\302\211 ... ': command not found' in xterm/sh?

07
2014-07
  • amn

    Sometimes when I simply type a valid command like 'find ...', or anything really, I get back the following, which is completely unexpected and confusing (... is command name I type):

    sh: $'\302\211...': command not found
    

    There is some corruption going on I think. I don't use color in my prompt, I am using the Bash shell in POSIX mode as sh (chsh to /bin/sh and so on - $SHELL is sh).

    What is going on and why does this keep happening? Anything I can debug? I think this is more of an xterm issue than sh, or at least a combination of the two.

    Files, for context:

    My /etc/profile, as distributed with Arch Linux x86-64:

    # /etc/profile
    
    #Set our umask
    umask 022
    
    # Set our default path
    PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
    export PATH
    
    # Load profiles from /etc/profile.d
    if test -d /etc/profile.d/; then
            for profile in /etc/profile.d/*.sh; do
                    test -r "$profile" && . "$profile"
            done
            unset profile
    fi
    
    # Source global bash config
    if test "$PS1" && test "$BASH" && test -r /etc/bash.bashrc; then
            . /etc/bash.bashrc
    fi
    
    # Termcap is outdated, old, and crusty, kill it.
    unset TERMCAP
    
    # Man is much better than us at figuring this out
    unset MANPATH
    

    My /etc/shrc, which I created as a way to have sh parse some file on startup, when non-login shell. This is achieved using ENV variable set in /etc/environment with the line ENV=/etc/shrc:

    PS1='\u@\H \w \$ '
    alias ls='ls -F --color'
    alias grep='grep -i --color'
    [ -f ~/.shrc ] && . ~/.shrc
    

    My ~/.profile, I am launching X when logging in through first virtual tty:

    [[ -z $DISPLAY && $XDG_VTNR -eq 1 ]] && exec xinit -- -dpi 111
    

    My ~/.xinitc, as you can see I am using the system as a Virtual Box guest:

    xrdb -merge ~/.Xresources
    
    VBoxClient-all
    
    awesome &
    
    exec xterm
    

    And finally, my ~/.Xresources, no fancy stuff here I guess:

    *faceName: Inconsolata
    *faceSize: 10
    xterm*VT100*translations: #override <Btn1Up>: select-end(PRIMARY, CLIPBOARD, CUT_BUFFER0)
    
    xterm*colorBDMode: true
    xterm*colorBD: #ff8000
    xterm*cursorColor: S_red
    

    Since ~/.profile references among other things /etc/bash.bashrc, here is its content:

    #
    # /etc/bash.bashrc
    #
    
    # If not running interactively, don't do anything
    [[ $- != *i* ]] && return
    
    PS1='[\u@\h \W]\$ '
    PS2='> '
    PS3='> '
    PS4='+ '
    
    case ${TERM} in
      xterm*|rxvt*|Eterm|aterm|kterm|gnome*)
        PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND; }'printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
    
        ;;
      screen)
        PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND; }'printf "\033_%s@%s:%s\033\\" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
        ;;
    esac
    
    [ -r /usr/share/bash-completion/bash_completion   ] && . /usr/share/bash-completion/bash_completion
    

    I have no idea what that case statement does, by the way, it does look a bit suspicious though, but then again, who am I to know.

  • Answers
  • jlliagre

    That's the ‰ character also used as "CHARACTER TABULATION WITH JUSTIFICATION".

    I guess you are using a specific keyboard or editor that uses this unusual character instead of the regular tab, which is normally ignored in shell command lines, or having a locale mismatch between the shell and the terminal emulator.


  • Related Question

    bash xterm : how to get command line before typing enter
  • Michel Xavier

    I try to define a custom behaviour of the backward-kill-word function in bash xterm. For that, I need to catch the command line before validate it. For instances, if I type sdcds/edfdD sdf/sdf without typing enter, I want by using a shortcut like esc + backspace to catch the line sdcds/edfdD sdf/sdf in a temporary variable to apply a sed after. I have already written the sed and the bind command but I cannot find anywhere how to catch the buffer command line.

    Update from Answer

    Ok thanks a lot, I think I'm not clear enough in my explanation. What I want to do is to create a function and the related bind key in the bash.rc to modify the text in the command line. Imagine, I want to define a function which removes the command line (before typing enter) till "/" for example and only till /, I could write in my .bash.rc :

    function backward-delete-to-slash () { echo $BUFFER_COMMAND_LINE | sed  's:\(.*[/][/]*).*:\1:';}
    
    bind -x '"\e\d": backward-delete-to-slash'
    

    My problem is to catch the command line into a $BUFFER_COMMAND_LINE variable. If I had this variable, I could do for instance :

    $: sdffs/dsfd dsfsdf/dfdsf (without typing enter)
    

    esc + backspace

    $: sdffs/dsfd dsfsdf/
    

    So I hope to be more exhaustive.


  • Related Answers
  • ott--

    If you know vi a bit, try this:

    $ set -o vi
    $ bind vi-yank-to '\ey'
    $ type-your-text-here - then press Home to go to begin-of-line, esc-y
    

    The line is in a buffer now. Press Ctrl-c to get a new line, then

    $ sed something-and-then esc-p
    

    The text from the buffer should appear.