Shell通配符不适用于Julia的Shell模式
运行 IPython 时,我可以运行任何前面带有感叹号的 shell 命令:
In [1]: !ls
file1 file2 file3 file4
In [2]: !ls file*
file1 file2 file3 file4
但是,某些事情(特别是使用 if 通配符)在 shell 模式下(在您输入分号之后)在 Julia REPL 上不起作用:
shell> ls file
file1 file4 file2 file3
shell> ls file*
ls: cannot access 'file*': No such file or directory
我在这里错过了什么吗?有没有办法让通配符像在 Linux shell 中一样正常运行?
回答
你是对的,Julia shell REPL 模式不是大多数人期望的 shell,可以在这里和这里找到一些讨论。目前,参数按原样传递,没有外壳扩展,因此如果程序支持正常工作的文字“*”:
shell> find -iname *
.
./file1
./file2
./file3
./file4
如果不是,你需要想出另一种方式。就像通过 bash 调用一样:
shell> bash -c 'ls *'
file1 file2 file3 file4
或者使用 Julia 函数/宏:
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))
- 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).