gopherdata/gophernotes

bash commands not available in the docker image

RafalSkolasinski opened this issue · 9 comments

Playing with gophernotes from docker I realized it is not possible to e.g. do

> !go get gopkg.in/src-d/go-git.v4
repl.go:1:2: expected operand, found 'go'

or even

> !ls
repl.go:1:2: undefined identifier: ls

It's not implemented.

A shell escape as you suggest is surely useful and quite easy to implement - it's a matter of extending func evalSpecialCommand(ir *interp.Interp, line string). It would be a good candidate for a first contribution.

Anyway, the character that starts a shell escape cannot be ! because it can already appear at the beginning of a regular Go expression.

Hi @cosmos72 / @RafalSkolasinski ,

I want to contribute to this repository.
Can you please guide me on how should I start solving this issue? I will be great help.

Hello @raghavgg ,

the following assumes you have at least basic experience with

Gophernotes implements its own special commands, with minimal line parsing, in the function evalSpecialCommand() in file kernel.go#L608.
It currently recognizes only two special commands: %go111module {on|off} and %help
Currently, every special command must be on its own line - i.e. you cannot mix it with Go code.

A good (and minimal) starting point is to extend the message printed by %help to also show the expected syntax for shell commands. For example it could print something like:

available special commands:
%go111module {on|off}
%help
$some shell command with parameters

The next step is importing the packages "os/exec" and "strings", modifying the function evalSpecialCommands() to check for lines starting with $, remove the initial $, then split the line with strings.Split(line, " ") and convert it to a struct exec.Cmd by calling cmd := exec.Command(line[0], line[1:]...).
Finally run the command with err := cmd.Run().

There are some more steps to polish everything, such as redirecting the command input and output, and showing the err returned by cmd.Run(), but the basic steps are described above.

Good luck!

shell commands implemented in commit 10097f0

Wait for a moment here, so was this problem solved?

I don't get it. Why I still get errors when I run !ls?

error:

repl.go:1:2: undefined identifier: ls

After struggling for a while, I found the solution here. You just have to use:

%ls

Which seems a little bit strange, because it conflicts with the python version of command line, where we use:

!ls

Is there any possibility that we change back to !ls? (smile

Well, IIRC, magic commands/modes in Jupyter are prefixed with %.
Also, in Go, contrary to python, ! is a valid unary operator (while '%' isn't).
So it makes more sense to use the former then the latter.

Exactly.
We could not use ! as prefix for shell commands, because !something already has a meaning in Go:
namely, it's an expression that returns the negation of something.

So the next best choice was to use the same prefix as other Jupyter special commands i.e. %

Update: I remembered incorrectly, the prefix to execute shell commands is $
image