How to execute run(`ls *.pdb`)?

How to run a command like this:

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

and, since we are here, can that that error message be improved? Maybe is my poor english, but adding "*", or '*', or \*, does not work, so I do not understand what must be quoted means there.

By the way, specifically here I want to get the number of files satisfying *.pdb, so I am not even sure if this is the right track, since I noticed now that I cannot automatically get the output of to a variable. Two things to check there.

Well, I did find this:

julia> length(filter(f -> f[end-2:end] == "pdb", readdir("./")))
21

but perhaps a simpler option exists. (I do not care with performance here, the clearer the better).

See https://github.com/vtjnash/Glob.jl

Note that that error is there so we can hopefully implement this in the future.

Another (not necessarily better, but sometimes most expedient) option is to just let your shell handle all the things that your shell normally handles:

julia> run(`sh -c 'ls -1d *'`)
base
cli
contrib
CONTRIBUTING.md
deps
doc
etc
HISTORY.md
julia
LICENSE.md
Makefile
Make.inc
Make.user
NEWS.md
README.md
src
stdlib
sysimage.mk
test
ui
usr
usr-staging
VERSION
Process(`sh -c 'ls -1d *'`, ProcessExited(0))

Nice, I like that. How can I get that output into a variable?

Maybe not the best way (I haven’t done a lot of process piping in Julia yet), but something that works is:

julia> buf = IOBuffer()
IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)

julia> run(pipeline(`sh -c 'ls -1d *'`, stdout=buf))
Process(`sh -c 'ls -1d *'`, ProcessExited(0))

julia> seek(buf, 0)
IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=175, maxsize=Inf, ptr=1, mark=-1)

julia> readlines(buf) # or just String(take!(buf)) to get as one String
23-element Vector{String}:
 "base"
 "cli"
 "contrib"
 "CONTRIBUTING.md"
 "deps"
 "doc"
 "etc"
 "HISTORY.md"
 "julia"
 "LICENSE.md"
 "Makefile"
 "Make.inc"
 "Make.user"
 "NEWS.md"
 "README.md"
 "src"
 "stdlib"
 "sysimage.mk"
 "test"
 "ui"
 "usr"
 "usr-staging"
 "VERSION"

And the beauty was lost :joy:

You can use read, like read(`sh -c 'ls -1d *'`, String)

Looks like that wasn’t — read-like functions works in several cases:

julia> readlines(`sh -c 'ls -1d *'`)
23-element Vector{String}:
 "base"
 "cli"
 "contrib"
 "CONTRIBUTING.md"
 "deps"
 "doc"
 "etc"
 "HISTORY.md"
 "julia"
 "LICENSE.md"
 "Makefile"
 "Make.inc"
 "Make.user"
 "NEWS.md"
 "README.md"
 "src"
 "stdlib"
 "sysimage.mk"
 "test"
 "ui"
 "usr"
 "usr-staging"
 "VERSION"

julia> String(read(`sh -c 'ls -1d *'`))
"base\ncli\ncontrib\nCONTRIBUTING.md\ndeps\ndoc\netc\nHISTORY.md\njulia\nLICENSE.md\nMakefile\nMake.inc\nMake.user\nNEWS.md\nREADME.md\nsrc\nstdlib\nsysimage.mk\ntest\nui\nusr\nusr-staging\nVERSION\n"

Now we are talking! Thank you all! :slight_smile: