An easy way to access files/folders/directories with Julia in command line based on language: batch-script

Hi all! Community Julia!

user stories

  1. I would like as a user to list files, folders, directories like I would in shell script or bat-script in the Julia programming language, because it would be an easy way
  2. I would like just 2 ls/dir commands that do the same thing but join Linux and Windows users. So… Normally you are a Windows user you find the prompt and type dir and if you are a Linux/Unix user generally you type ls

So… here “my solution”:

before

julia> pwd()
"/home/JuliaUser"

after

julia> julia --dir #=> background: pwd()
"/home/JuliaUser"

sample 1: before

julia> cd(readdir, "/home/JuliaUser/Projects/julia")
34-element Array{String,1}:
 ".circleci"
 ".freebsdci.sh"
 ".git"
 ".gitattributes"
 ".github"
 ⋮
 "test"
 "ui"
 "usr"
 "usr-staging"

sample 1.1: after

julia> julia ls --readdir "/home/JuliaUser/Projects/julia" #=> background: cd(readdir, "/home/JuliaUser/Projects/julia")
 ".circleci"
 ".freebsdci.sh"
 ".git"
 ".gitattributes"
 ".github"
 ⋮
 "test"
 "ui"
 "usr"
 "usr-staging"

sample 1.2: after

julia> julia dir --readdir "/home/JuliaUser/Projects/julia" #=> background: cd(readdir, "/home/JuliaUser/Projects/julia")
 ".circleci"
 ".freebsdci.sh"
 ".git"
 ".gitattributes"
 ".github"
 ⋮
 "test"
 "ui"
 "usr"
 "usr-staging"

sample 1.3: after

julia> julia dir "/home/JuliaUser/Projects/julia" #=> background: cd("/home/JuliaUser/Projects/julia")
 ".circleci"
 ".freebsdci.sh"
 ".git"
 ".gitattributes"
 ".github"
 ⋮
 "test"
 "ui"
 "usr"
 "usr-staging"

sample 1.4: after

julia> julia ls "/home/JuliaUser/Projects/julia" #=> background: cd("/home/JuliaUser/Projects/julia")
 ".circleci"
 ".freebsdci.sh"
 ".git"
 ".gitattributes"
 ".github"
 ⋮
 "test"
 "ui"
 "usr"
 "usr-staging"

other case 1

julia> ./  #=> background: cd("/home/JuliaUser/Projects/julia")
 ".circleci"
 ".freebsdci.sh"
 ".git"
 ".gitattributes"
 ".github"
 ⋮
 "test"
 "ui"
 "usr"
 "usr-staging"

other case 2

julia> "/home/JuliaUser/Projects/julia"  #=> background: cd("/home/JuliaUser/Projects/julia")
 ".circleci"
 ".freebsdci.sh"
 ".git"
 ".gitattributes"
 ".github"
 ⋮
 "test"
 "ui"
 "usr"
 "usr-staging"

other case 3

julia> "c://mytests//main.jl"  #=> background: cd("c:/mytests/main.jl")
┌ Info:
└ Web Server starting at http://127.0.0.1:8888

my log

julia> ls
ERROR: UndefVarError: ls not defined

julia> dir
ERROR: UndefVarError: dir not defined

julia> path
ERROR: UndefVarError: path not defined

julia> dir
ERROR: UndefVarError: dir not defined

julia> julia main.jl
ERROR: syntax: extra token "routes" after end of expression
Stacktrace:
 [1] top-level scope
   @ none:1

julia> julia C:\mytests\main.jl
ERROR: syntax: extra token "C" after end of expression
Stacktrace:
 [1] top-level scope
   @ none:1

julia> C:\mytests\main.jl
ERROR: syntax: "\" is not a unary operator
Stacktrace:
 [1] top-level scope
   @ none:1

draft

julia> dir c:/mytests/main.jl # call powershell with command dir(Windows)
julia> ls c:/mytests/main.jl # call powershell with command ls(Linux/Unix)
julia> dir "c:/mytests/main.jl" # call powershell with command dir(Windows)
julia> ls "c:/mytests/main.jl" # call powershell with command ls(Linux/Unix)

why

  1. Makes life easier for those who came from shell script/batscript/python in Julia - Based on that, I made this proposal.
  2. I know that each programming language has its concept and specificity, but… listing files, folders and directories in Batchscript is trivial, you can use in the command line something like ls/dir - it just works the easy way… Julia should list things like directories, files, folders in an easy way like batscript - this is my initial opinion as someone who is studying Julia. Based on that, I made this proposal.
  3. I don’t have much knowledge in the Julia programming language, despite having taken programming courses in the Julia programming language, I have difficulties in understanding how Julia works… this can help me in this sense to better understand how Julia works if have ls/dir because … my initial difficulty was to list files, folders and directories with the Julia programming language. (Note: Over time… I can learn how to use Julia through experience) - I mentioned this because other people might feel like I do, they might be beginners and have been through the same problem as me. Based on that, I made this proposal.
  4. The point I want to make clear is from my experience as a beginner and someone interested in contributing to the Julia community. Based on that, I made this proposal.
  5. The files are called directly via the command line which makes it easier in Julia … Based on that, I made this proposal

references

Commandline switches are a somewhat expensive commodity to maintain, so I’m doubtful this would be sufficient for such a large change. It would also be breaking, as e.g. julia> "/home/JuliaUser/Projects/julia" already has the meaning of just returning the string in the REPL. Julia is not a shell after all.

1 Like

Are you aware of the shell> REPL mode accessible via ; ?

5 Likes

I tried …

log 1

C:\mytests\>julia ; powershell
ERROR: SystemError: opening file "C:\\mytests\\;": No such file or directory
Stacktrace:
  [1] systemerror(p::String, errno::Int32; extrainfo::Nothing)
    @ Base .\error.jl:174
  [2] #systemerror#68
    @ .\error.jl:173 [inlined]
  [3] systemerror
    @ .\error.jl:173 [inlined]
  [4] open(fname::String; lock::Bool, read::Nothing, write::Nothing, create::Nothing, truncate::Nothing, append::Nothing)
    @ Base .\iostream.jl:293
  [5] open
    @ .\iostream.jl:282 [inlined]
  [6] open(f::Base.var"#364#365"{String}, args::String; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Base .\io.jl:328
  [7] open
    @ .\io.jl:328 [inlined]
  [8] read
    @ .\io.jl:436 [inlined]
  [9] _include(mapexpr::Function, mod::Module, _path::String)
    @ Base .\loading.jl:1249
 [10] include(mod::Module, _path::String)
    @ Base .\Base.jl:418
 [11] exec_options(opts::Base.JLOptions)
    @ Base .\client.jl:292
 [12] _start()
    @ Base .\client.jl:495

log 2

julia> ; # upon typing ;, the prompt changes (in place) to: shell>

shell> dir
ERROR: IOError: could not spawn `dir`: no such file or directory (ENOENT)
Stacktrace!
.......

@Sukera @carstenbauer What do you think of this idea?

my idea

julia> ; powershell 
julia> ; prompt 
julia> shell powershell # ; powershell 
julia> shell prompt  # ; prompt 
julia> ; main.jl # call powershell with command dir(Windows)/ls(Linux/Unix)
julia> ; "./" # call powershell with command dir(Windows)/ls(Linux/Unix)
julia> ; ./ # call powershell with command dir(Windows)/ls(Linux/Unix)
julia> ; "c:/mytests/main.jl" # call powershell with command dir(Windows)/ls(Linux/Unix)
julia> ; c:/mytests/main.jl # call powershell with command dir(Windows)/ls(Linux/Unix)

Main arguments

  1. Any programming language must be accessible to people
  2. Doing things like listing files, folders and folders should be easy in any programming language
  3. A language must have some clear working purpose for developers
  4. This might solve the log 1 and log 2 problem
  5. If you don’t have these commands like dir/ls… then put the symbol ; to allow absolute or partial paths

references

I don’t understand. What is it you want that readdir doesn’t do?

2 Likes

Hi! @gustaphe

  1. I would just like a command line to list files, directories or folders… in the shell. just that. … something like ls/dir…
  2. I tried …
C:\mytests\>julia ; powershell
ERROR: SystemError: opening file "C:\\mytests\\;": No such file or directory
Stacktrace:
  [1] systemerror(p::String, errno::Int32; extrainfo::Nothing)
    @ Base .\error.jl:174

and

julia> ; # upon typing ;, the prompt changes (in place) to: shell>

shell> dir
ERROR: IOError: could not spawn `dir`: no such file or directory (ENOENT)
Stacktrace!
.......

So something like

#!/bin/julia
# juliadir.jl
function print_directory(directory)
    println.(readdir(directory))
    return nothing
end
print_directory(get(ARGS, 1, pwd()))
$ chmod +x juliadir.jl
$ ./juliadir.jl ~/.julia
artifacts
compiled
config
dev
environments
juliaup
logs
packages
pluto_notebooks
registries
scratchspaces

?

1 Like

I think the OP is on Windows. The “;” is very ineffectual on Windows.
I would suggest to install Git, and run julia in the Git bash. Then all those commands
that the OP would have liked to see would be available.

1 Like

Okay I think we need some clarification. Does OP need something that runs from a command line, or something that runs a shell from julia? Because if it’s the former, my function works, but will be a bit less usable than simply aliasing ls to dir (It might be you need to run it as $ julia juliadir.jl thedirectory in Windows). If it’s the latter I’m back to not seeing the issue with readdir.

1 Like

The Julia REPL shell mode does work as a typical “unix-ish” shell mode on windows. On posix/unix systems, the shell mode in the REPL will run a shell while on windows it does what I’ll call an “execute mode” since there is not really a default shell on windows.

I haven’t figured out how to make shell mode on windows run a shell (even if it is in the PATH) but if you install some shell such as the git bash one or (my preferred option) use a cygwin install and add the cygwin bin directory to the end of your windows PATH. It is usually in someplace like C:\cygwin64\bin.

Then you will at least have the commands for the standard unix utilities from cygwin even if you have to run a shell/powershell/cmd by hand to get full shell capability.

It would be nice if the REPL shell mode allowed one to configure this to work on windows—if you have a shell in the PATH.

Hope this helps.

1 Like

@gustaphe @PetrKryslUCSD … Hi all! Here … my “solution” and you guys are right

#!/bin/julia
# batchscript.jl

# List files, directories, folders in shell
function filepath(directory)
    println.(readdir(directory))
    return nothing
end

# windows_specific_thing(a) or linux_specific_thing(a) or generic_thing(a)
function filesystem(parameter):
    if Sys.iswindows() || Sys.islinux()
        filepath(parameter)
    else
        return nothing # filepath(parameter)
    end
end

# list all files/directories/folders with symbol: ["./"] or ["dir"] or ["ls"] or [";"] or ["path"] in shell-julia 
function batchscript(parameter): 
    # Calling rdeadline() function
    string = readline() 
    if string == "dir" || string == "ls" || string ==  ";" || string == "./" || string == "--dir" || string == "--ls" || string == "-ls" || string == "-dir" || string == "--readdir" || string == "-readdir" || string == "readdir"
        # call function 'os'
        filesystem(parameter)
    else # or => "; powershell" || "; cmd"
        return nothing
        end
    end

# case 1: dir "~/.julia" || case 2: ls "~/.julia" || case 3: ; "~/.julia" || case 4: ./ "~/.julia"
batchscript(get(ARGS, 1, pwd())) # add path: "~/.julia"

use cases

julia> using batchscript
julia> ls "~/.julia"
julia> dir "~/.julia"
julia> "~/.julia"
julia> ./ "~/.julia"
julia> ; "~/.julia"
julia> -dir "~/.julia"
julia> --dir "~/.julia"
julia> -ls "~/.julia"
julia> --ls "~/.julia"
julia> -readdir "~/.julia"
julia> --readdir "~/.julia"
julia> readdir "~/.julia"

notes

  1. current_path: dirname(pwd()) for ./ or ls or dir or readdir or ;
  2. list files/directories/folders: println.(readdir(get(ARGS, 1, pwd()))) "~/.julia"

references

1 Like
  • Yeah… truth… that’s right.

What I don’t understand it’s why you would do this with a readline and a bunch of string comparisons instead of just readdir directly?

A couple of tips anyway:

  • Try to name functions and variables a bit more self-explanatorily, batchscript, filesystem, parameter and filepath are all a bit opaque
  • Instead of chaining x == "a" || x == "b" || ..., you can use x in ("a", "b", ...)
  • readdir is (to best effort) OS agnostic, so you don’t need to check
  • Comments are good, but a comment that tells you which function is called on the next line doesn’t really add any information
1 Like

@gustaphe thank you very much for the feedback … I will improve my code. You are awesome