9

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).

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.

  • This answer is the closest to what was asked for by the OP. – reza.safiyat Jul 4 '17 at 12:57
  • Slightly different syntax in this answer, &TIOCSTI is a bit nicer than 0x5412 too. Worth noting it sounds like some platforms (e.g. OpenBSD) disable TIOCSTI though. I think that means both this approach and zsh's print -z wouldn't work. – dimo414 Mar 22 at 19:50
4

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.

  • The problem is that if I do history -s 'foo' in a script, the history of the launched shell is not modified at all – gioele Jul 12 '13 at 8:15
  • @gioele You have to launch it from within the shell (e.g. from a script that you load with source). You can't do anything from a separate process. – Gilles Jul 12 '13 at 19:43
2

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

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.