I'm sometimes logged in on a host which I do not control and where PROMPT_COMMAND is readonly. Is there some way to work around this to run history commands anyway, for example using PS1? I've tried PS1='$(history -a; history -c; history -r; echo finished)' - It prints finished at each prompt, but it doesn't seem to work:

  1. Open two terminals A and B on the same host.
  2. In terminal A, run a command a.
  3. In terminal B, run a command b.
  4. It terminal B, press twice.

On a host where PROMPT_COMMAND='history -a; history -c; history -r;', this will result in terminal B showing a. On a host where PS1 starts with $(history -a; history -c; history -r; echo finished) it will instead show whichever command was run before both terminals were opened. The obvious reason is that the command in PS1 is run in a subshell.

Another alternative is to bypass the global RC-file altogether:

bash --rcfile ~/.bashrc

However, circumventing the use of the standard value of PROMPT_COMMAND will very likely not be accepted by the sysadmin for policy reasons.

  • 2
    You can work around a readonly var by spawning a new shell, with an alternate rc file. – jordanm Aug 23 '12 at 15:17
  • 1
    @jw013 I have lots of command substitutions in PS1 which work, but this one has to update the state of the parent shell, which is probably not possible. – l0b0 Aug 23 '12 at 15:25
  • 1
    @jw013 Presumably the PROMPT_COMMAND is doing some kind of logging by policy. @l0b0 Would the admins object to your using zsh if you supplied a precmd that's similar to their PROMPT_COMMAND? – Gilles Aug 23 '12 at 20:42
  • 1
    Please. I'd rather discuss the technical issue. – l0b0 Aug 24 '12 at 2:06
  • 2
    @l0b0 The technical issue has been solved - get a non-readonly PROMPT_COMMAND by running a new shell. Ignoring real-life when making technical decisions is a recipe for outrageous setups. Sounds like you have much deeper non-technical problems if you can't even run a new shell. – jw013 Aug 24 '12 at 13:57

You could run the history commands in a signal handler, avoiding the use of a subshell. Then have PS1 send the appropriate signal:

trap 'history -a; history -c; history -r;' USR1
export PS1='$(kill -USR1 $$)'"$PS1"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.