0

I am scripting in Ruby and want to insert a command in the history for the Zshell that calls the Ruby script. I've tried this but it can't access the calling Zshell (I think)

#!/usr/bin/env ruby
`zsh -c print -s what`

Any hints?

Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421
  • 1
    A child process can't modify its parent's environment (see e.g. https://stackoverflow.com/a/263022/2088135) – Tom Fenech Jun 09 '17 at 15:21
  • I'm not sure this is possible, because there is a ``.zsh_history`` file but it's only loaded on startup; the current shell doesn't reference it all, instead just keeping its history in memory. If you open a new terminal and run something, it won't be added to any open shells. Unless there's some zsh function you can call to add something to the memory of all open shells (or at least a single open shell), you might be out of luck. – Piccolo Jun 09 '17 at 15:23
  • @piccolo I could run `fc -R` to reload a modified Zshell, but I think we're into the same problem again, right? – Dan Rosenstark Jun 09 '17 at 15:28
  • Oh hey, I did not know about that command. In that case, you can just append to ``.zsh_history``, if you're okay with manually running ``fc -R`` after the Ruby program exits. Maybe you could write some sort of zsh function that, after running a (specific?) Ruby program, it runs ``fc -R``. – Piccolo Jun 09 '17 at 15:34
  • @Piccolo that's great, but either way... no way to just put this nicely into the Ruby script. Oh well... Thanks! If you want to put that as an answer here, I'm glad to accept it. – Dan Rosenstark Jun 09 '17 at 15:43
  • I was just writing that up! – Piccolo Jun 09 '17 at 15:46

1 Answers1

1

One way you can go about doing this is as follows:

Make a zsh function that calls fc -R after it finishes executing a certain command as follows:

function rb_yourprogram {
  ruby /path/to/your/program.rb && fc -R
}

In Ruby, append to the ~/.zsh_history file:

File.open("~/.zsh_history", "a") do |f|
    f.puts "adds this line to history"
end

Now, you can call the program by typing rb_yourprogram into zsh, and after it finishes executing it will reload the history file and thus will have this new line of history (in addition to anything written into other zsh instances during the time since you opened the first shell).

You could also overload the ruby command in zsh so that it will always call fc -R after finishing execution:

function ruby {
  builtin ruby "$@" && fc -R
}
Piccolo
  • 1,612
  • 4
  • 22
  • 38
  • Thanks, I was trying to do this here: https://gist.github.com/drosenstark/3557dfebd73857cb724a59a33bbbc1cc but this solution -- though amazing -- is a bit too clever for my taste. But there's no choice, I guess... – Dan Rosenstark Jun 09 '17 at 15:52
  • My god that's complicated. I was wanting to do this from a regular shell script. – Sridhar Sarnobat May 06 '20 at 01:57
  • 1
    @SridharSarnobat if you're doing this from a shell script, that should be as easy as just concatenating the line to the `~/.zsh_history` file and running `fc -R`, I think – Piccolo May 07 '20 at 19:43