Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

preexec $1 is missing some commands #147

Open
alperyilmaz opened this issue Oct 6, 2023 · 1 comment
Open

preexec $1 is missing some commands #147

alperyilmaz opened this issue Oct 6, 2023 · 1 comment

Comments

@alperyilmaz
Copy link

I'm recording command history in certain format into daily log files. I was using PROMPT_COMMAND to save the last command to a file. I was using echo "$(history -p \!-1)" to save the last item from history to a file. But that is causing some problems: 1) the command is recorded in log file when next command is run. 2) due to ignored commands (ls, cd, ll, clear, etc.) "last command" approach becomes out of sync.

I discovered bash-preexec and it is exactly what I want "record the command as soon as I hit Enter with preexec() function"

I updated by .bashrc accordingly, the concept is working but somehow preexec is missing some commands and do not record them and instead prints the previous command to log file. The ones that I noticed are;

  • ignored commands, ls, ll, clear
  • function definitions are not recorded in the log file (for example :hello-world () { echo "hello world!"; })

Here's my old PROMPT_COMMAND:

export PROMPT_COMMAND='history -a; history -n; if [ "$(id -u)" -ne 0 ]; then echo -ne "$(date "+%Y-%m-%d.%H:%M:%S")\t$(hostname)\t$(pwd)\t"; echo "$(history -p \!-1)" >> ~/.logs/bash-history-$(hostname)-$(date "+%Y-%m-%d").log; fi'

Here's my new PROMPT_COMMAND:

export PROMPT_COMMAND='history -a; history -n;'

And here's my preexec() function:

preexec() { echo -e "$(date "+%Y-%m-%d.%H:%M:%S")\t$(hostname)\t$(pwd)\t$1" >> ~/.logs/bash-history-$(hostname)-$(date "+%Y-%m-%d").log; }

What should I do so that whatever I write in prompt is saved to log file as soon as I hit Enter

@akinomyoga
Copy link
Contributor

The ones that I noticed are;

  • ignored commands, ls, ll, clear

I guess that it is caused by your HISTIGNORE. If the command matches any of the patterns in HISTIGNORE, it is not registered into the command history of Bash, so history -p '!-1' will pick up the last command that does not match HISTIGNORE even though preexec is invoked on the commands matching HISTIGNORE.

But this problem should also happen with your previous approach using PROMPT_COMMAND as it also uses history -p '!-1'.

You can also refer to #6 (comment) for the settings that can affect the behavior of history -p '!-1'.

  • function definitions are not recorded in the log file (for example :hello-world () { echo "hello world!"; })

This is already reported in #6. This is a limitation of the current way of implementing preexec. The current implementation relies on the DEBUG trap, but DEBUG trap is not activated for function definitions.

What should I do so that whatever I write in prompt is saved to log file as soon as I hit Enter

If you can assume Bash >= 4.4, you may use PS0='$(your command)'. Since your commands do not modify the shell environment, you can use the command substitution $() which will be run in a subshell. Note that the general preexec cannot be implemented using PS0='$(your command)' since preexec also assumes modifications to the environment of the main shell by the registered command. See also discussions in #28.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants