Avoid clobbering $? in PROMPT_COMMAND #99

Closed
wants to merge 3 commits into
from

Conversation

Projects
None yet
5 participants

Utilizes a trick - backticks work both where a command is expected and
where an argument is expected, so we don't need to worry about whether
or not PROMPT_COMMAND was empty to start with, or whether it ended with
a semicolon.

This is safe to do because the call to _z will never print anything out
(thanks to the &>/dev/null). It behaves as a no-op in the command
position, and doesn't affect the number of arguments passed to the
command if this comes in the argument position (since it's not quoted
and the expansion is empty).

Fixes #90

Avoid clobbering $? in PROMPT_COMMAND
Utilizes a trick - backticks work both where a command is expected and
where an argument is expected, so we don't need to worry about whether
or not PROMPT_COMMAND was empty to start with, or whether it ended with
a semicolon.

This is safe to do because the call to _z will never print anything out
(thanks to the &>/dev/null).  It behaves as a no-op in the command
position, and doesn't affect the number of arguments passed to the
command if this comes in the argument position (since it's not quoted
and the expansion is empty).
Contributor

notwa commented May 26, 2013

mine was a quick fix, but this is just evil. I like it.

Contributor

notwa commented May 26, 2013

This case doesn't work. I assume _z in the backticks is setting $? before PCMD is run.

- cat ~/.bashrc
PCMD() { [ $? = 0 ] && PS1="- " || PS1="! "; }
PROMPT_COMMAND=PCMD
- false
! true
- . z.sh
- false
- echo "$PROMPT_COMMAND"
PCMD `_z --add "$(pwd -P 2>/dev/null)" &>/dev/null`;

Hm, yeah, I hadn't considered that case. OK... maybe saving and restoring $? is really the simplest thing to do...

Owner

rupa commented Jun 15, 2013

Does the new behavior fix this up?

Hi, awesome tool @rupa !

I'm not sure if this is related:

-bash: PROMPT_COMMAND: line 0: syntax error near unexpected token `;'
-bash: PROMPT_COMMAND: line 0: `update_terminal_cwd; ;_z --add "$(pwd -P 2>/dev/null)" 2>/dev/null;'

This happen on any bash command. Next time line 0 would be line 1

-bash: PROMPT_COMMAND: line 1: syntax error near unexpected token `;'
-bash: PROMPT_COMMAND: line 1: `update_terminal_cwd; ;_z --add "$(pwd -P 2>/dev/null)" 2>/dev/null;'

UPDATE: I temporarily solve it with $_Z_NO_PROMPT_COMMAND. What's the difference setting this var?

Any idea of why is this happening?
Thanks!

@lemattma getting the same error. How did you set the variable?

Hm. I'm guessing that the problem is that your PROMPT_COMMAND ends with a trailing space (judging by the error message), and rupa's code only tries to remove /;$/, not /;\s*$/. So, we still need a more robust solution to this problem.

Owner

rupa commented Jun 23, 2013

@lemattma you certainly want PROMPT_COMMAND working. As @godlygeek mentioned, something is adding update_terminal_cwd to the PROMPT_COMMAND with a trailing space, before z gets to it, and that trailing space is throwing off zs attempt to play nice with what's already there.

godlygeek added some commits Jun 23, 2013

Alternate approach for appending to PROMPT_COMMAND
Our basic problem with appending to the end of $PROMPT_COMMAND was that
we couldn't put 2 semicolons in a row.  We can, however, put 2 newlines
in a row, which seems to be treated identically.  As far as I can tell,
this approach works whether PROMPT_COMMAND is unset, set to an empty
string, or set to a non-empty string with or without a trailing
semicolon.

Added an alternate approach to solving this issue that seems to solve all of our problems. My test cases for this approach were:

unset PROMPT_COMMAND                 ; PROMPT_COMMAND="$PROMPT_COMMAND"$'\n'"echo 1"
PROMPT_COMMAND=                      ; PROMPT_COMMAND="$PROMPT_COMMAND"$'\n'"echo 2"
PROMPT_COMMAND=$' \n \n '            ; PROMPT_COMMAND="$PROMPT_COMMAND"$'\n'"echo 3"
PROMPT_COMMAND=" echo 4 "            ; PROMPT_COMMAND="$PROMPT_COMMAND"$'\n'"echo 5"
PROMPT_COMMAND=" echo  6 ; echo 7; " ; PROMPT_COMMAND="$PROMPT_COMMAND"$'\n'"echo 8"

Paste into bash, and you'll see the numbers 1 through 8 in order with no duplicates.

I've tested this with bash 2.0 and 4.2.37, so using a newline to separate commands inside PROMPT_COMMAND has worked since at least 1997 up through now. So, this approach seems portable, too.

@seafarer What I did was to add this var in the .bash_profilefile:

_Z_NO_PROMPT_COMMAND=true
. ~/Shell_Scripts/z/z.sh

However, I suggest to follow a better solution like the one @godlygeek and @rupa are implementing. I'll test this out (what's the branch or how should I just merge the master?). Will let you know if it's working after the patch.

Thanks guys!

@rupa rupa closed this in ea574b7 Jun 24, 2013

@lemattma, you should be able to use the latest master (after ea574b7). I believe that version should fix your problem.

@godlygeek godlygeek deleted the godlygeek:prompt_command_append branch Jun 24, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment