5

When running IPython I can run any shell command with an exclamation mark in front it:

In [1]: !ls
file1  file2  file3  file4

In [2]: !ls file*
file1  file2  file3  file4

However, some things (in particular the use if wildcards) don't work on the Julia REPL in shell mode (after you type in the semicolon):

shell> ls file
file1 file4  file2  file3
shell> ls file*
ls: cannot access 'file*': No such file or directory

Am I missing something here? Is there a way to get wildcards to behave as they do normally in a Linux shell?

TomCho
  • 3,204
  • 6
  • 32
  • 83

2 Answers2

5

You're right, the Julia shell REPL mode is not a shell in the sense most people expect, some discussion can be found here and here. Currently, the arguments are passed as is, with no shell expansion so if the program supports a literal '*' that works fine:

shell> find -iname *
.
./file1
./file2
./file3
./file4

If it doesn't you need to figure out another way. Like calling through bash:

shell> bash -c 'ls *'
file1  file2  file3  file4

Or using Julia functions/macros:

julia> bash(str::String) = run(`bash -c $str`)
bash (generic function with 1 method)

julia> macro sh_str(str::String)
       bash(str)
       end

julia> sh"ls *"
file1  file2  file3  file4
Process(`bash -c 'ls *'`, ProcessExited(0))
ahnlabb
  • 2,017
  • 1
  • 6
  • 16
  • 2
    Just to complement this excellent answer, the rationale for not using shell expansion is that in this way you don't depend on the system shell, which makes your program more portable. The trick to call `bash` works only if you have `bash`. As mentioned in one of the issues linked by the answer, in principle one could add common Unix shell features in command parsing to Julia (like globbing, I/O redirection, etc), but that would need to be done in a cross-platform way (i.e., without actually calling system's shell). – giordano Mar 02 '21 at 12:06
  • Thanks for the explanation. I still don't understand why the REPL can't simply take whatever is typed after `;` and throw it in the machine's shell (be it shell or otherwise). Then it's up to the user to use the correct commands for their shell. As far as I know IPython does that very successfully in all systems. – TomCho Mar 02 '21 at 14:30
0

It works here (Windows 10 with Win-builds ls). You might try ls --version in your Python and your Julia shell? Are the files in your Python root working directory and not in your Julia one?

shell> ls --version
ls (GNU fileutils) 3.16

shell> ls file*
file1.txt  file2.txt  file3.txt  file4.txt
desertnaut
  • 57,590
  • 26
  • 140
  • 166
Bill
  • 5,600
  • 15
  • 27