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 GitHub - vtjnash/Glob.jl: Posix-compliant file name pattern matching

3 Likes

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

1 Like

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))
1 Like

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)

2 Likes

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"
3 Likes

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

1 Like