1

I would like to write a perl script that do something similar to what fc do. Indeed I want to edit programmatically the last command executed. Something like this should work

perl -wle 'print system("/bin/bash", "-i", "-c", "history | tail -n 1")'

but system return the exit status of the command executed, not the stdout, that is what I want, while I'm not able to activate the history (-i flag) using back-tic, qx// or opening a pipe.

I know that using back-tic, qx// or opening a pipe it is simple to read the stdout of the command, but int this case how to use the builtin bash hisotry command properly?

Even using system and passing -i to bash, I'm not able to get the expected output from history | tail -n 1. Bi redirecting the output to a file I found its content empty.

perl -wle 'print system("/bin/bash", "-i", "-c", "history | tail -n 1 > /tmp/pippo")'

So am I forced to write the bash history on a file whit history -w and to read that file inside perl?

mox
  • 447
  • 6
  • 15
  • 1
    Take a look [here](https://stackoverflow.com/questions/2415954/how-can-i-store-perls-system-function-output-to-a-variable) – John Doe Feb 21 '18 at 11:43
  • 2
    Why don't you just read the `~/.bash_history` file directly? – xxfelixxx Feb 21 '18 at 11:46
  • @Borodin To me it seems more similar to what I suggested. The question doesn't ask what is the diffrence between `system` and other ways to make a call, it asks how to store the result of a `system` call in a variable, which is the same with what is asked [here](https://stackoverflow.com/questions/2415954/how-can-i-store-perls-system-function-output-to-a-variable) – John Doe Feb 21 '18 at 12:25
  • Dear @Borodin and @John, I know that using back-tic, `qx//` or opening a pipe it is simple to obtain the output of the command. The problem is that with `system` is possible to pass `-i` to bash, not with other methods. If it is mandatory I will force a write on `~/.bash_history` and then i will read the penultimate row of the file (see my comment to @xxfelixxx answer), I was just asking if there is a more elegant way. – mox Feb 21 '18 at 17:02
  • @JohnDoe thanks, but I'm not able to run properly the `history` command. – mox Feb 21 '18 at 17:18
  • Why can't you pass an `-i` option to `qx//`? – Borodin Feb 21 '18 at 17:52

1 Answers1

0

Use qx to capture shell command output. Read the ~/.bash_history file directly since you cannot capture the output of the shell builtin function history.

You may need to add history -a to your .bashrc file to get bash to write the history file after every command, or add history -w to your bash PROMPT_COMMAND. Other settings are covered nicely over at unix.stackexchange.com.

$ echo "foo"
foo
$ perl -e 'chomp(my $cmd = qx(tail -n 1 ~/.bash_history)); print "$cmd bar\n";'
echo "foo" bar
xxfelixxx
  • 6,512
  • 3
  • 31
  • 38
  • That is not reading the file directly. Doing so would involve using `open`, not spawning external commands – Chris Turner Feb 21 '18 at 14:49
  • The bash history is not written every time a command is launched. On my system your example does not work. So I have to do `$echo "foo"`, then `$ history -w`, and then `perl -e 'chomp(my $cmd = qx(tail -n 2 ~/.bash_history| head -n 1)); print "$cmd bar\n";'`. I'm looking to some more elegant solution if exists. – mox Feb 21 '18 at 16:56
  • You can add 'history -a' to your .bashrc to have it get written out after every command. – xxfelixxx Feb 21 '18 at 23:56
  • @ChrisTurner, what I meant by using the history file directly was to read the history file, not to try to invoke bash and use its history builtin. You are correct that we could just read the file from within perl, but then you need to read through the file and print the last line...when tail -n 1 does this for you) – xxfelixxx Feb 22 '18 at 00:55