zsh-users
 help / color / mirror / code / Atom feed
* /usr/bin/printf
@ 2009-02-13  1:41 Matthew Flaschen
  2009-02-13  1:51 ` /usr/bin/printf Mikael Magnusson
  0 siblings, 1 reply; 12+ messages in thread
From: Matthew Flaschen @ 2009-02-13  1:41 UTC (permalink / raw)
  To: zsh-users

zsh (zsh 4.3.4 (i686-pc-linux-gnu)) seems to use (probably for
optimization) its built-in printf even if you explicitly specify
/usr/bin/printf .  Of course, this is only coming up because zsh's
printf seems to be wrong (or it least doesn't match the executable it's
mimicking)

Under bash:

$ printf "%s\n" foo
foo

Under dash (or bash):

$ /usr/bin/printf "%s\n" foo
foo

Under zsh:

% printf "%s\n" foo

" foofoo

/usr/bin/printf "%s\n" foo

" foofoo

zsh's printf does some really bizarre things:

% /usr/bin/printf "%s" > /dev/null
" > /dev/null

It actually prints the text /dev/null !

Under bash:

$ /usr/bin/printf "%s" > /dev/null
$

Is this a known issue?

Matt Flaschen


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: /usr/bin/printf
  2009-02-13  1:41 /usr/bin/printf Matthew Flaschen
@ 2009-02-13  1:51 ` Mikael Magnusson
  2009-02-13  3:04   ` /usr/bin/printf Matthew Flaschen
  0 siblings, 1 reply; 12+ messages in thread
From: Mikael Magnusson @ 2009-02-13  1:51 UTC (permalink / raw)
  To: zsh-users

2009/2/13 Matthew Flaschen <matthew.flaschen@gatech.edu>:
> zsh (zsh 4.3.4 (i686-pc-linux-gnu)) seems to use (probably for
> optimization) its built-in printf even if you explicitly specify
> /usr/bin/printf .  Of course, this is only coming up because zsh's
> printf seems to be wrong (or it least doesn't match the executable it's
> mimicking)
>
> Under bash:
>
> $ printf "%s\n" foo
> foo
>
> Under dash (or bash):
>
> $ /usr/bin/printf "%s\n" foo
> foo
>
> Under zsh:
>
> % printf "%s\n" foo
>
> " foofoo
>
> /usr/bin/printf "%s\n" foo
>
> " foofoo
>
> zsh's printf does some really bizarre things:
>
> % /usr/bin/printf "%s" > /dev/null
> " > /dev/null
>
> It actually prints the text /dev/null !
>
> Under bash:
>
> $ /usr/bin/printf "%s" > /dev/null
> $
>
> Is this a known issue?

This is because your preexec() function is broken and is outputting
the newline from the cmdline without escaping it, which makes your
terminal stop reading the title, and the rest of the command line is
just echoed. This is kind of hard to figure out the first time.

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: /usr/bin/printf
  2009-02-13  1:51 ` /usr/bin/printf Mikael Magnusson
@ 2009-02-13  3:04   ` Matthew Flaschen
  2009-02-13  3:25     ` /usr/bin/printf Bart Schaefer
  2009-02-13  8:20     ` /usr/bin/printf Dan Nelson
  0 siblings, 2 replies; 12+ messages in thread
From: Matthew Flaschen @ 2009-02-13  3:04 UTC (permalink / raw)
  To: zsh-users

Mikael Magnusson wrote:
> This is because your preexec() function is broken and is outputting
> the newline from the cmdline without escaping it, which makes your
> terminal stop reading the title, and the rest of the command line is
> just echoed. This is kind of hard to figure out the first time.

Okay, here's my preexec.  I admit I don't understand this syntax yet:

preexec () { print -Pn "\e]0;%n@%m: $1\a" }

I got it from
http://web.archive.org/web/20071224181948/www.princeton.edu/~kmccarty/zsh.html

Do you know how I would correct it?

Matt Flaschen


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: /usr/bin/printf
  2009-02-13  3:04   ` /usr/bin/printf Matthew Flaschen
@ 2009-02-13  3:25     ` Bart Schaefer
  2009-02-13  3:40       ` /usr/bin/printf Nikolai Weibull
  2009-02-13  4:09       ` /usr/bin/printf Matthew Flaschen
  2009-02-13  8:20     ` /usr/bin/printf Dan Nelson
  1 sibling, 2 replies; 12+ messages in thread
From: Bart Schaefer @ 2009-02-13  3:25 UTC (permalink / raw)
  To: zsh-users

On Feb 12, 10:04pm, Matthew Flaschen wrote:
}
} Mikael Magnusson wrote:
} > This is because your preexec() function is broken and is outputting
} > the newline from the cmdline without escaping it
} 
} Okay, here's my preexec.  I admit I don't understand this syntax yet:
} 
} preexec () { print -Pn "\e]0;%n@%m: $1\a" }
} 
} I got it from
} http://web.archive.org/web/20071224181948/www.princeton.edu/~kmccarty/zsh.html
} 
} Do you know how I would correct it?

The problem is that $1 is first expanded by the command parser and then
passed to "print".  When $1 contains the substring "\n", "print" turns
that into a newline.  So you need to quote the value of $1 against
further expansion by "print".

preexec () { print -Pn "\e]0;%n@%m: ${(q)1}\a" }

The (q) tells zsh to insert a backslash before any special characters
that appear in the value of $1, including the backslash in "\n".  Then
"print" strips the extra backslashes off again and the final output is
the original string.

Or, well, it would be, except there's that -P option there, which will
turn any %x (for any x) in your $1 into some sort of prompt expando.
So you really need to do this in two steps, one to do the prompt
expansion and one to handle the value of $1.

preexec () { print -Pn "\e]0;%n@%m: "; print -n "${(q)1}\a" }


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: /usr/bin/printf
  2009-02-13  3:25     ` /usr/bin/printf Bart Schaefer
@ 2009-02-13  3:40       ` Nikolai Weibull
  2009-02-13  4:12         ` /usr/bin/printf Bart Schaefer
  2009-02-13  4:13         ` /usr/bin/printf Matthew Flaschen
  2009-02-13  4:09       ` /usr/bin/printf Matthew Flaschen
  1 sibling, 2 replies; 12+ messages in thread
From: Nikolai Weibull @ 2009-02-13  3:40 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-users

On Fri, Feb 13, 2009 at 04:25, Bart Schaefer <schaefer@brasslantern.com> wrote:

> The problem is that $1 is first expanded by the command parser and then
> passed to "print".

> The (q) tells zsh to insert a backslash before any special characters
> that appear in the value of $1, including the backslash in "\n".  Then
> "print" strips the extra backslashes off again and the final output is
> the original string.

Couldn't one use the -r switch to print as well?

Also, it seems that you would more or less always want to make sure to
do this whenever printing anything.

I think it's really unfortunate that print has the same default
interpretation of its arguments as echo.  It would have been nice if
there was a command that didn't interpret escapes by default.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: /usr/bin/printf
  2009-02-13  3:25     ` /usr/bin/printf Bart Schaefer
  2009-02-13  3:40       ` /usr/bin/printf Nikolai Weibull
@ 2009-02-13  4:09       ` Matthew Flaschen
  1 sibling, 0 replies; 12+ messages in thread
From: Matthew Flaschen @ 2009-02-13  4:09 UTC (permalink / raw)
  To: zsh-users

Bart Schaefer wrote:
> The (q) tells zsh to insert a backslash before any special characters
> that appear in the value of $1, including the backslash in "\n".  Then
> "print" strips the extra backslashes off again and the final output is
> the original string.
> 
> Or, well, it would be, except there's that -P option there, which will
> turn any %x (for any x) in your $1 into some sort of prompt expando.
> So you really need to do this in two steps, one to do the prompt
> expansion and one to handle the value of $1.

Okay, that makes sense.

> preexec () { print -Pn "\e]0;%n@%m: "; print -n "${(q)1}\a" }

It works great.  Thanks.

Matt Flaschen


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: /usr/bin/printf
  2009-02-13  3:40       ` /usr/bin/printf Nikolai Weibull
@ 2009-02-13  4:12         ` Bart Schaefer
  2009-02-13  4:13         ` /usr/bin/printf Matthew Flaschen
  1 sibling, 0 replies; 12+ messages in thread
From: Bart Schaefer @ 2009-02-13  4:12 UTC (permalink / raw)
  To: zsh-users

On Feb 13,  4:40am, Nikolai Weibull wrote:
} Subject: Re: /usr/bin/printf
}
} On Fri, Feb 13, 2009 at 04:25, Bart Schaefer <schaefer@brasslantern.com> wrote:
} 
} > The (q) tells zsh to insert a backslash before any special characters
} > that appear in the value of $1, including the backslash in "\n".
} 
} Couldn't one use the -r switch to print as well?

One could, except that in this case the strings \e and \a are *meant*
to be expanded by print.  So, you could do *three* prints:

precmd() { print -Pn "\e]0;%n@%m: "; print -rn "$1"; print -n "\a" }

} I think it's really unfortunate that print has the same default
} interpretation of its arguments as echo.  It would have been nice if
} there was a command that didn't interpret escapes by default.

Alas, zsh did not invent "print", it copied it from ksh.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: /usr/bin/printf
  2009-02-13  3:40       ` /usr/bin/printf Nikolai Weibull
  2009-02-13  4:12         ` /usr/bin/printf Bart Schaefer
@ 2009-02-13  4:13         ` Matthew Flaschen
  2009-02-13  4:21           ` /usr/bin/printf Andrey Borzenkov
  2009-02-13 10:40           ` /usr/bin/printf Mikael Magnusson
  1 sibling, 2 replies; 12+ messages in thread
From: Matthew Flaschen @ 2009-02-13  4:13 UTC (permalink / raw)
  To: zsh-users

Nikolai Weibull wrote:
> On Fri, Feb 13, 2009 at 04:25, Bart Schaefer <schaefer@brasslantern.com> wrote:
> 
>> The problem is that $1 is first expanded by the command parser and then
>> passed to "print".
> 
>> The (q) tells zsh to insert a backslash before any special characters
>> that appear in the value of $1, including the backslash in "\n".  Then
>> "print" strips the extra backslashes off again and the final output is
>> the original string.
> 
> Couldn't one use the -r switch to print as well?

Well, it can't be used for the whole thing, because some escapes are
supposed to be used.  I tested, and:

preexec () { print -Pn "\e]0;%n@%m: "; print -rn "$1"; print -n "\a" }

does works I'm not really sure why there's a \a at the end anyway.  I
presume this doesn't mean system bell here.

Matt Flaschen


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: /usr/bin/printf
  2009-02-13  4:13         ` /usr/bin/printf Matthew Flaschen
@ 2009-02-13  4:21           ` Andrey Borzenkov
  2009-02-13 10:40           ` /usr/bin/printf Mikael Magnusson
  1 sibling, 0 replies; 12+ messages in thread
From: Andrey Borzenkov @ 2009-02-13  4:21 UTC (permalink / raw)
  To: zsh-users

[-- Attachment #1: Type: text/plain, Size: 303 bytes --]

On 13 of February 2009 07:13:54 Matthew Flaschen wrote:
> preexec () { print -Pn "\e]0;%n@%m: "; print -rn "$1"; print -n "\a"
> }
>
> does works I'm not really sure why there's a \a at the end anyway.  I
> presume this doesn't mean system bell here.
>

It is part of ESC sequence to set (xterm) title.

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: /usr/bin/printf
  2009-02-13  3:04   ` /usr/bin/printf Matthew Flaschen
  2009-02-13  3:25     ` /usr/bin/printf Bart Schaefer
@ 2009-02-13  8:20     ` Dan Nelson
  1 sibling, 0 replies; 12+ messages in thread
From: Dan Nelson @ 2009-02-13  8:20 UTC (permalink / raw)
  To: Matthew Flaschen; +Cc: zsh-users

In the last episode (Feb 12), Matthew Flaschen said:
> Mikael Magnusson wrote:
> > This is because your preexec() function is broken and is outputting the
> > newline from the cmdline without escaping it, which makes your terminal
> > stop reading the title, and the rest of the command line is just echoed. 
> > This is kind of hard to figure out the first time.
> 
> Okay, here's my preexec.  I admit I don't understand this syntax yet:
> 
> preexec () { print -Pn "\e]0;%n@%m: $1\a" }
> 
> I got it from
> http://web.archive.org/web/20071224181948/www.princeton.edu/~kmccarty/zsh.html
> 
> Do you know how I would correct it?

Here's what I use.  Possibly overkill.  The extra escape string in the
$+WINDOW=1 case truncate the window names within screen to 10 chars so that
"^A W" can still display a lot of titles even if your commandline in window
1 is long.  Truncating the title itself to 100 characters helps if you're
editing a huge commandline (say you manually expanded a 500-arg wildcard for
some reason; no need to send all that to xterm).


# strip control chars and replace with "."
# result is returned in $reply
function _strip()
{
  local i=1
  reply=$1
  while (( i <= $#1 )) ; do
    [[ $reply[i] > $'\C-_' && $reply[i] < $'\C-?' ]] || reply[i]="."
    (( i ++ ))
  done
}

SHOST=$(print -P %m)

if [[ $+WINDOW = 1 && $TERM = screen* ]] ; then
  preexec () { _strip $1 ; echo -En "^[k${reply[1,10]:gs/ /_/}^[\\^[]0;$SHOST: ${reply[1,100]}\a" }
else
  case $TERM in
    xterm*|screen*)
      preexec () { _strip $1 ; echo -En "^[]0;$SHOST: $reply[1,100]\a" } ;;
  esac
fi


-- 
	Dan Nelson
	dnelson@allantgroup.com


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: /usr/bin/printf
  2009-02-13  4:13         ` /usr/bin/printf Matthew Flaschen
  2009-02-13  4:21           ` /usr/bin/printf Andrey Borzenkov
@ 2009-02-13 10:40           ` Mikael Magnusson
  2009-02-13 10:45             ` /usr/bin/printf Mikael Magnusson
  1 sibling, 1 reply; 12+ messages in thread
From: Mikael Magnusson @ 2009-02-13 10:40 UTC (permalink / raw)
  To: zsh-users

2009/2/13 Matthew Flaschen <matthew.flaschen@gatech.edu>:
> Nikolai Weibull wrote:
>> On Fri, Feb 13, 2009 at 04:25, Bart Schaefer <schaefer@brasslantern.com> wrote:
>>
>>> The problem is that $1 is first expanded by the command parser and then
>>> passed to "print".
>>
>>> The (q) tells zsh to insert a backslash before any special characters
>>> that appear in the value of $1, including the backslash in "\n".  Then
>>> "print" strips the extra backslashes off again and the final output is
>>> the original string.
>>
>> Couldn't one use the -r switch to print as well?
>
> Well, it can't be used for the whole thing, because some escapes are
> supposed to be used.  I tested, and:
>
> preexec () { print -Pn "\e]0;%n@%m: "; print -rn "$1"; print -n "\a" }
>
> does works I'm not really sure why there's a \a at the end anyway.  I
> presume this doesn't mean system bell here.

The \a is the endcode for the title setting command, it is just an
arbitrary value really, as much as \e and ] are. That said, I don't
think this command works if you put literal \a on your command line.
This is what I use:

#for changing a *term title
function ct() {
  local MATCH
  if [[ "$1" = "-e" ]]; then
    #nulls terminate the string when printed, so change them
    printf '\e]0;%s\007' ${${${2//$'\x00'/\^@}//
/\\n}//(#m)[$'\x00'-$'\x1f']/$'\x16'$MATCH}
  elif [[ "$1" = "-t" ]]; then
    pts="$2"
    ct -e "$3" > /dev/pts/$pts
  else
    ct -e "$*"
  fi
}

To be honest, I can't say off hand what all those parts do, they're
sort of stacked on top of eachother until it stopped letting anything
through.

My actual preexec() calls it like this:
if [ "$#1" -gt 512 ];then 1=${1[1,512]}; fi
ct -e "$TTY:t [$1] {`print -P "%100<...<%~%<<"`} `strftime "%x %T"
$EPOCHSECONDS`"

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: /usr/bin/printf
  2009-02-13 10:40           ` /usr/bin/printf Mikael Magnusson
@ 2009-02-13 10:45             ` Mikael Magnusson
  0 siblings, 0 replies; 12+ messages in thread
From: Mikael Magnusson @ 2009-02-13 10:45 UTC (permalink / raw)
  To: zsh-users

2009/2/13 Mikael Magnusson <mikachu@gmail.com>:
> The \a is the endcode for the title setting command, it is just an
> arbitrary value really, as much as \e and ] are. That said, I don't
> think this command works if you put literal \a on your command line.
> This is what I use:
>
> #for changing a *term title
> function ct() {
>  local MATCH
>  if [[ "$1" = "-e" ]]; then
>    #nulls terminate the string when printed, so change them
>    printf '\e]0;%s\007' ${${${2//$'\x00'/\^@}//
> /\\n}//(#m)[$'\x00'-$'\x1f']/$'\x16'$MATCH}

Well I remember what this part does now, it puts a literal ^V before
every byte between 0 and 0x1f, which is a trick that probably only
works in rxvt-unicode, I have this commented out below which seems to
work more generally:
#   #(q) instead of (V) is also an option
    printf '\e]0;%s\007' ${${2//
/\\n}//(#m)[$'\x00'-$'\x1f']/${(V)MATCH}}

>  elif [[ "$1" = "-t" ]]; then
>    pts="$2"
>    ct -e "$3" > /dev/pts/$pts
>  else
>    ct -e "$*"
>  fi
> }
>
> To be honest, I can't say off hand what all those parts do, they're
> sort of stacked on top of eachother until it stopped letting anything
> through.
>
> My actual preexec() calls it like this:
> if [ "$#1" -gt 512 ];then 1=${1[1,512]}; fi
> ct -e "$TTY:t [$1] {`print -P "%100<...<%~%<<"`} `strftime "%x %T"
> $EPOCHSECONDS`"
>
> --
> Mikael Magnusson
>



-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2009-02-13 10:46 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-13  1:41 /usr/bin/printf Matthew Flaschen
2009-02-13  1:51 ` /usr/bin/printf Mikael Magnusson
2009-02-13  3:04   ` /usr/bin/printf Matthew Flaschen
2009-02-13  3:25     ` /usr/bin/printf Bart Schaefer
2009-02-13  3:40       ` /usr/bin/printf Nikolai Weibull
2009-02-13  4:12         ` /usr/bin/printf Bart Schaefer
2009-02-13  4:13         ` /usr/bin/printf Matthew Flaschen
2009-02-13  4:21           ` /usr/bin/printf Andrey Borzenkov
2009-02-13 10:40           ` /usr/bin/printf Mikael Magnusson
2009-02-13 10:45             ` /usr/bin/printf Mikael Magnusson
2009-02-13  4:09       ` /usr/bin/printf Matthew Flaschen
2009-02-13  8:20     ` /usr/bin/printf Dan Nelson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).