3

I created a flirt.sh script which just outputs a random sentence with a random color, and now I want it to be ran every time I enter a command

I used trap "~/flirt.sh" DEBUG in .bashrc for that purpose but there's a small problem:

for i in 1; do
    echo $i
done

runs flirt.sh two times, and if I use for i in {1..2} the output will be 2 times from script and 1, after that another 2 times from script and 2 e.g., so for each command in loop it runs script 2 times. I'm searching for a method to run command (script) one time after I press enter and before command I typed starts executing, so something like this:

# Nothing typed so script won't be executed
$
# Script and command will be executed
$ ls
Hello from flirt.sh!

Documents Downloads
...

# Script will be executed only once
$ for i in {1..2}; do echo $i; done
Hello from flirt.sh!

1
2

Any tips, please?

3
  • 1
    After every command (as you've asked), or actually for every shell prompt? Commented Jan 28, 2022 at 15:11
  • 1
    For every shell prompt only, as I’ve described in my example
    – xezo360hye
    Commented Jan 28, 2022 at 16:34
  • This Q/A is very useful for revealing the witchcraft that is the trap command. I find this to be the answer to my own related question: how to achieve hiding the cursor during command execution and showing it again later. (Hint use escape sequences \e[?25l)
    – Samie Bee
    Commented Jun 23, 2022 at 6:51

1 Answer 1

2

You've clarified in a comment that you really want the command to run only for every prompt. What isn't directly available in bash is, "a method to run command […] after I press enter and before command I typed starts executing". However, a work-around is available using trap '…' DEBUG.

Here are two suggestions for you

  1. PROMPT_COMMAND. This feature runs a command immediately before each prompt. The documentation for bash (see man bash) writes,

    PROMPT_COMMAND If set, the value is executed as a command prior to issuing each primary prompt.

    Examples

    PROMPT_COMMAND='date'
    PROMPT_COMMAND='printf "Date: %s Id: %s\n" "$(date)" "$(id -un)"'
    PROMPT_COMMAND='echo "Command 1"; echo "Command 2"'
    
  2. trap '…' DEBUG. As you have already discovered this will allow you to run a command immediately before it's executed. The documentation writes for trap,

    If a sigspec is DEBUG, the command arg is executed before every simple command, for command, case command, select command, every arithmetic for command, and before the first command executed in a shell function

    So, what we can do here is to have the trap run your Flirt.sh command only once after each prompt, using a toggle to suppress it after the first time until the next prompt is received.

    PROMPT_COMMAND='_trace=yes'
    trap '[[ "$_trace" == "yes" ]] && echo Flirt.sh; _trace=no' DEBUG
    

    Here I've used echo Flirt.sh as a substitute for your flirt.sh script.

    Sample session

    $ date
    Flirt.sh
    28 Jan 2022 16:57:51
    $ for i in 1 2 3; do echo i=$i; done
    Flirt.sh
    i=1
    i=2
    i=3
    $
    
  3. Do not trigger when there’s no command

    Adding a simple check for $BASH_COMMAND can preserve from miss-trigger

    trap 'cmd="$BASH_COMMAND"; [[ "$cmd" != "$PROMPT_COMMAND" ]] && echo ~/.Flirt.sh' DEBUG
    
5
  • 1
    Please correct COMMAND_PROMPT to PROMPT_COMMAND, and I have a question, can I make it not to trigger if I didn’t type any commend (just pressed enter)?
    – xezo360hye
    Commented Jan 28, 2022 at 20:53
  • 1
    @xezo360hye thank you for pointing out that typo. Incidentally, you would have been welcome to edit the answer and fix it. I did have a look around to see if I could avoid a trigger on an empty command but I couldn't get anywhere, even with extdebug, $ARGC, and $BASH_COMMAND Commented Jan 28, 2022 at 21:40
  • 1
    Ok, I’ll try it myself, if I could find something I’ll add to answer. Also I didn’t know that I can edit somebody’s answer, thank you for that
    – xezo360hye
    Commented Jan 29, 2022 at 7:00
  • Does enabling this debug option have any significant impact on the performance, or any side effects an user should be aware of?
    – Neinstein
    Commented May 19, 2023 at 10:43
  • 1
    @Neinstein I would expect that any significant difference would be from the impact of the code that the trap runs, more than the presence of the trap itself. It shouldn't affect the execution of bash scripts, so the impact will be seen, if at all, only for interactive use Commented May 19, 2023 at 10:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .