I'm writing "scripts" in Julia, that I use from the command line. For example:
#!/usr/bin/env julia
#info "Hello world!"
Using a shebang line like this makes it possible to make such a script executable and easily run it without explicitly invoking julia:
$ ./hello
[ Info: Hello world!
However, passing additional command-line arguments to julia in such a shebang line is not portable (at least does not work for Linux, which I care about). Is there a way to overcome this limitation? For example, how could I make sure that my script will be run with julia -O0 --compile=min?
The recommended way to do this is documented in the FAQ. Adapting the example to your case:
#!/bin/bash
#=
exec julia -O0 --compile=min "${BASH_SOURCE[0]}" "$#"
=#
#info "Hello world!"
Related
I have a script main.jl which prints a simple "Hello world" string:
println("Hello world!")
However, when trying to run the script through the terminal like this:
julia> main.jl
I get the error:
ERROR: type #main has no field jl
All the information I can find online suggests calling the script like I do to run it. I have assured that I'm in the correct directory - what am I doing wrong?
You are trying to run the file from the Julia REPL (as indicated by the julia> prompt at the beginning of the line). There, you have to include the file as #AndreWildberg mentions. This will run the commands from the file as if you had typed them into the REPL.
The information you found online might have been about running Julia from "normal" terminal, aka a console shell like bash on Linux. There, running julia main.jl will run the program, although the REPL method above is usually preferred for working with Julia.
(question about calling the script with arguments asked in the comment):
First of all, I'll mention that this is not the usual workflow with Julia scripts. I've been writing Julia code for years, and I had to look up how to handle command-line arguments because I've never once used them in Julia: usually what's done instead is that you define the functions you want in the file, with maybe a main function, and after doing an include, you call the main function (or whichever function you want to try out) with arguments.
Now, if your script already uses command-line arguments (and you don't want to change that), what you can do is assign to the variable that holds them, ARGS, before the include statement:
julia> push!(empty!(ARGS), "arg1")
1-element Vector{String}:
"arg1"
julia> include("main.jl")
Here we empty the ARGS to make sure any previous values are gone, then push the argument (or arguments) we want into it. You can try this out for educational purposes, but if you are new to the language, I would suggest learning and getting used to the more Julian workflow involving function calls that I've mentioned above.
The julia> prompt means your terminal is in Julia REPL mode and is expecting valid Julia code as input. The Julia code main.jl would mean that you want to return the value of a field named jl inside a variable named main. That is why you get that error. The Julia code you would use to run the contents of a file is include("main.jl"). Here the function include is passed the name of your file as a String. This is how you should run files from the REPL.
The instructions you read online are assuming your terminal is in shell mode. This is usually indicated by a $ prompt. Here your terminal is expecting code in whatever language your shell is using e.g. Bash, PowerShell, Zsh. When Julia is installed, it will (usually) add a julia command which works in any shell. The julia command by itself will transform your terminal from shell mode to REPL mode. This julia command can also take additional arguments like filenames. If you use the command julia main.jl in this environment, it will run the file using the Julia program and then exit you back to your terminal shell. This is how you should run files from the terminal shell.
A third way to run Julia files would be to install an IDE like VSCode. Then you can run code from a file with keyboard shortcuts rather than by typing commands.
See the Getting Started Documentation for more information.
Adding to Sundar R's answer, if you want to run script which takes commandline arguments from REPL, you can check this package: https://github.com/v-i-s-h/Runner.jl
It allows you to run you script from REPL with args like:
julia> #runit "main.jl arg1 arg2"
See the README.md for detailed examples.
How can I call an external command (as if I had typed it into the Windows command prompt or Unix shell) from within a Julia program? I know this is possible with other languages but I'm not sure how to do it in Julia.
According to the Julia docs,
The command is never run with a shell. Instead, Julia parses the command syntax directly, appropriately interpolating variables and splitting on words as the shell would, respecting shell quoting syntax. The command is run as Julia's immediate child process, using fork and exec calls.
A simple example is as follows:
julia> testcommand = `echo HelloWorld`
`echo HelloWorld`
julia> typeof(testcommand)
Cmd
julia> run(testcommand);
HelloWorld
See the docs linked above for a deeper dive of the low-level details occurring of what is going on here.
I am a beginner at Lisp, having only used DrRacket for some dabbling in Racket/Scheme. I have had much trouble figuring out how to run a .lisp file with Clozure CL for Windows. I tried running a .lisp file in SBCL on Ubuntu (running on virtualbox) without success as well.
I should mention that I've looked into the related questions about running files but I wasn't able to see any direct solution. Some are using .bat files, some are "creating applications" with Clozure CL's image (or something along those lines).
For SBCL in Ubuntu, I've tried:
sbcl lisptest.lisp \ The python/forth way.
(load "lisptest.lisp")
(load lisptest.lisp)
(--load lisptest.lisp)
:cd C:\Temp
(:cd C:\Temp)
and more.
I also tried to run it from notepad++:
cmd /k C:\Temp\ccl-1.11-windows\ccl\wx86cl64.exe "$(FULL_CURRENT_PATH)"
which is how I usually execute python files, but this method hasn't been successful.
**I will definitely start learning to use Emacs and Slime (Emacs is the obvious choice for lisp). But for the sake of knowledge, I would appreciate some tips on the alternative, basic-text-editor way of getting something trivial like "hello world" to print without my typing it explicity into the REPL and instead interpreting (or compiling) a text file with the instruction.
Thanks for your help.
Typically programs have help - did you look at that?
SBCL, Ubuntu, from the shell:
A Common Lisp file:
$ cat test.lisp
(format t "Hello World~%~%")
SBCL shows help:
$ sbcl --help
Usage: sbcl [runtime-options] [toplevel-options] [user-options]
Common runtime options:
--help Print this message and exit.
--version Print version information and exit.
--core <filename> Use the specified core file instead of the default.
--dynamic-space-size <MiB> Size of reserved dynamic space in megabytes.
--control-stack-size <MiB> Size of reserved control stack in megabytes.
Common toplevel options:
--sysinit <filename> System-wide init-file to use instead of default.
--userinit <filename> Per-user init-file to use instead of default.
--no-sysinit Inhibit processing of any system-wide init-file.
--no-userinit Inhibit processing of any per-user init-file.
--disable-debugger Invoke sb-ext:disable-debugger.
--noprint Run a Read-Eval Loop without printing results.
--script [<filename>] Skip #! line, disable debugger, avoid verbosity.
--quit Exit with code 0 after option processing.
--non-interactive Sets both --quit and --disable-debugger.
Common toplevel options that are processed in order:
--eval <form> Form to eval when processing this option.
--load <filename> File to load when processing this option.
User options are not processed by SBCL. All runtime options must
appear before toplevel options, and all toplevel options must
appear before user options.
For more information please refer to the SBCL User Manual, which
should be installed along with SBCL, and is also available from the
website <http://www.sbcl.org/>.
Using the script option from above:
$ sbcl --script test.lisp
Hello World
The same for Clozure CL
$ ccl --help
usage: ccl <options>
where <options> are one or more of:
-h, --help : this text
-V, --version : print (LISP-IMPLEMENTATION-VERSION) and exit
-K, --terminal-encoding : specify character encoding to use for *TERMINAL-IO*
-n, --no-init : suppress loading of init file
-e, --eval : evaluate <form> (may need to quote <form> in shell)
-l, --load : load <file>
-T, --set-lisp-heap-gc-threshold : set lisp-heap-gc-threshold to <n>
-Q, --quiet : if --batch, also suppress printing of heralds, prompts
-R, --heap-reserve <n>: reserve <n> (default: 1610612736)
bytes for heap expansion
-S, --stack-size <n>: set size of initial thread's control stack to <n>
-Z, --thread-stack-size <n>: set default size of first (listener) thread's stacks based on <n>
-b, --batch: exit when EOF on *STANDARD-INPUT*
--no-sigtrap : obscure option for running under GDB
--debug : try to ensure that kernel debugger uses a TTY for I/O
-I, --image-name <image-name>
and <image-name> defaults to ccl.image
Any arguments following the pseudoargument "--" are
not processed and are available to the application as
the value of CCL:*UNPROCESSED-COMMAND-LINE-ARGUMENTS* .
Using the load option from above
$ ccl --load test.lisp --eval '(quit)'
Hello World
 
Try
C:/path/to/ccl -l lisptest.lisp
This should work the same as
(load "lisptest.lisp")
If you can let us know specifically how that fails, we can be of more help.
How can I check documentation for R code from a Linux command shell such as bash? I DO NOT mean an interactive session.
With Perl, I can use perldoc to print out documentation at the command line:
perldoc lib
I was hoping for something simple like that for R. I don't always want to pull up a full interactive R session just to look up some documentation.
There might be other ways, but one that works for me is using the -e flag to execute code on the command line. I also use the --slave flag, which prevents anything from being printed to standard output (e.g. no R startup messages, etc.):
R --slave -e '?function'
I actually created a super small script I call rdoc to act like a simple R version of perldoc:
#!/bin/bash
R --slave -e "?$1"
After installing that in my ~/bin directory (or however you install it in your PATH), it's easy:
rdoc function
If you want to look at documentation of a function from a particular package, prepend the library name followed by two colons. For example, to pull up documentation of the dmrFinder function from the charm package:
rdoc charm::dmrFinder
I'm trying to call a script in Tcl with the command:
exec source <script path>
and I get the error
couldn't execute "source": no such file or directory
How can I call another script from tcl?
Edit: I am running a command I got from another person in my office. I was instructed to run "source " explicitly with source. So in other words, how would I run any command that would work in cshell, in Tcl?
If the script you were given is a cshell script, you can exec it like this:
exec /bin/csh $path_to_script
In effect, this is what the 'source' command does from within an interactive shell. It's not clear whether this is really what you want to do or not (not exactly, but close enough for this discussion).
The reason you can't exec the source command is that exec will only work on executable files (hence the name 'exec'). The source command isn't implemented as an exectuable file, it is a command built-in to the shell. Thus, it can't be exec'd.
If you really feel the need to exec the source command or any other built-in command you can do something like this:
exec /bin/csh -c "source $path_to_script"
In the above example you are execing the c shell, and asking it to run the command "source ". For the specific case of the source command, this doesn't really make much sense.
However, I'm not sure any of this will really do what you expect. Usually if someone says "here's some commands, just do 'source ', it usually just defines some aliases and whatnot to be used from within an interactive shell. Those aliases won't work from within Tcl.
source in csh, like . in bash, executes a script without spawning a new process.
The effect is that any variable that is set in that script is available in current csh session.
Actually, source is a built-in command of csh, thus not available from tcl exec, and using exec without source would not give the specific source effect.
There is no simple way to solve your problem.
source load the source file
you should do:
source <script path>
If you want to execute it, then you need to call the main proc.
another option would be to do:
exec [info nameofexecutable] <scritp path>
Some confusion here. exec runs a separate program, possibly with arguments.
source is not a separate program, it is another Tcl command which reads a file of Tcl commands and executes them, but does not pass arguments. If the other script you are trying to call is written to be run on from the command line, it will expect to find its arguments as a list in variable argv. You can fake this by setting argv to the list of arguments before running source, eg.
set argv {first_arg second_arg}
source script_path
Alternatively you could use exec to start a whole separate Tcl executable and pass it the script and arguments:
exec script_path first_arg second_arg
the error speaks for itself. Make sure you give the correct path name, specify full path if necessary. and make sure there is indeed the file exists in that directory
Recently I wanted to set some UNIX environment variables by sourcing a shell script and stumbled across the same problem. I found this simple solution that works perfectly for me:
Just use a little 3-line wrapper script that executes the source command in a UNIX shell before your Tcl script is started.
Example:
#!/bin/csh
source SetMyEnvironment.csh
tclsh MyScript.tcl