12

I would like to programmatically put a certain piece of text in the command line buffer of bash, read to be edited and used as a command.

What I am looking forward to is something similar to read -i but for commands.

-i text If readline is being used to read the line, text is placed into the editing buffer before editing begins.

Edit: With programmatically I mean that want to write this in a script, launch the script and have the command buffer prepared or the command history modified (as some questions have suggested).

gioele
  • 2,139

4 Answers4

6

I found a hacky way of doing this on the fzf examples page. This works with bash 4.3 and perl 5.18:

writecmd () { 
  perl -e 'ioctl STDOUT, 0x5412, $_ for split //, do{ chomp($_ = <>); $_ }' ; 
}

# Example usage
echo 'my test cmd' | writecmd

It prints out the command to stdout, but copies it to the command buffer as well. There is also an example on the linked page if you want to execute the command directly.

trhodes
  • 61
5

If this for a function that you're going to use in a readline binding with bind -x then you can modify READLINE_LINE. (Example)

Outside of a readline binding, you can push a fake command onto the history with history -s.

3

Gilles' answer is correct, but not completely satisfying. As I read this question, the OP wants to "preseed" the next input line. In my case I wanted to read the terminal's current position in my PROMPT_COMMAND function. That works but uses the same read buffer as the primary shell's, and so any user input gets discarded by the fact that I did a 'read' builtin call in the function. So I wanted to read the user input separately, do my terminal read, and then put the read input back in the input buffer, which is the original question. Note that this is indeed within the same process, so theoretically it should be possible.

As far as I can see (on my bash 4.2) there is no function to push something to the input stack programmatically. In zsh there is using 'print -z'.

So the answer is: this is not possible in bash, you need to use zsh for this.

0

As an alternative to history -s 'foo' try:

echo 'foo' >> ~/.bash_history
history -n

# or
history -s 'foo'
history -a
history -n
kcd
  • 11