Documentation for shell mode?

I really like the REPL’s shell mode (the thing you get after typing ;). But I struggle with understanding which features of my normal $SHELL are available, and which don’t work. I’ve read the official docs, but I can’t find the answers to these questions:

  • Why aren’t the aliases I define in my e.g. ~/.zshrc available?
  • Can I do any job control (run things in the background with &, etc.)?
  • Why can’t I set shell variables?

Is there anywhere I can find the answers to this questions?

I run Julia on Linux if it matters, and I use zsh as my shell.

2 Likes

Julia shell is not really using *your shell. In fact, it’s not running a shell at all, for example, ls * doesn’t work because * is expanded by shell program (bash, zsh) and Julia is not using any of them.

you can, however, run zsh as the first thing at shell > and that will drop you into your zsh. But I don’t think that is a particularly useful workflow, you might as well just Ctrl-Z the Julia instead

3 Likes

Thanks for the reply!

After looking at the code a bit more, I think it’s the opposite: Julia is escaping special characters before passing a command to my shell. I think the escaping is done by Base.shell_parse https://github.com/JuliaLang/julia/blob/master/base/shell.jl before being passed to my shell through Base.repl_cmd https://github.com/JuliaLang/julia/blob/master/base/client.jl#L33. I think that happens for the ; shell mode in REPL.jl: https://github.com/JuliaLang/julia/blob/master/stdlib/REPL/src/REPL.jl#L921.

So I guess the next question is: why does Julia need to escape special characters like * before passing them to the shell?

Thanks!

Daniel

it’s not about the escaping:

julia> run(`ls *`)
ERROR: LoadError: parsing command `ls *`: special characters "#{}()[]<>|&*?~;" must be quoted in commands
Stacktrace:

julia> run(`ls \*`)
ls: cannot access '*': No such file or directory
ERROR: failed process: Process(`ls '*'`, ProcessExited(2)) [2]

It’s passing * to ls just fine, but you have to realize that ls doesn’t know what to do with *. In a shell like bash, when you execute ls *, shell expands the * before passing arguments to ls. Julia shell doesn’t do that, it passes the argument (*) to ls directly – because Julia is not running a shell for you.

To further demonstrate this point, the following works by invoking a shell that expands *:

julia> run(`sh -c ls \*`)
...
..
.
1 Like