So I have a simple file.scm file with following code in it:
#!/usr/bin/guile -s
!#
(define (printer arg)
(display arg))
I know you can execute it inside guile repl by doing a (load "file.scm"), and then by invoking the function like (printer "this").
Is there is any way to run that function through the command-line terminal
such as guile "file.scm" (printer "this") ?
According to the manual, something like
guile -l file.scm -c '(printer "this")'
will work.
You could just use the -e flag
guile -e printer file.scm 1 2 3
Or better yet
#!/usr/bin/env -S guile -e printer
!#
(define (printer args)
(display args))
and run as
./file.scm 1 2 3
Many other (official) Guile Scripting examples: https://www.gnu.org/software/guile/manual/html_node/Scripting-Examples.html
Related
I am executing some commands in guile shell.
I want the results of the command written to a file.
I tried something like this:
some command | nc localhost abc >> file.txt
But did not work for me.
You need to display the results, in order to redirect them:
guile -c '(display (+ 1 2 3 4)) (newline)' > output
I tried the following and it worked.
echo -e "(define out (open-output-file \"/opt/ncOutput.txt\"))\n(display \"hello world\" out)\n(close-output-port out)\n" | nc localhost abc
IO operations with Guile
I want to pass command line options that start with a dash (- or --) to a Perl programm I am running with the -e flag:
$ perl -E 'say #ARGV' -foo
Unrecognized switch: -foo (-h will show valid options).
Passing arguments that don't start with a - obviously work:
$ perl -E 'say #ARGV' foo
foo
How do I properly escape those so the program reads them correctly?
I tried a bunch of variations like \-foo, \\-foo, '-foo', '\-foo', '\\-foo'. None of those work though some produce different messages. \\-foo actually runs and outputs \-foo.
You can use the -s, like:
perl -se 'print "got $some\n"' -- -some=SOME
the above prints:
got SOME
From the perlrun:
-s enables rudimentary switch parsing for switches on the command
line after the program name but before any
filename arguments (or before an argument of --). Any switch found there is removed from #ARGV and sets
the corresponding variable in the Perl program. The following program prints "1" if the program is
invoked with a -xyz switch, and "abc" if it is invoked with -xyz=abc.
#!/usr/bin/perl -s
if ($xyz) { print "$xyz\n" }
Do note that a switch like --help creates the variable "${-help}", which is not compliant with "use strict
"refs"". Also, when using this option on a script with warnings enabled you may get a lot of spurious
"used only once" warnings.
For the simple arg-passing use the --, like:
perl -E 'say "#ARGV"' -- -some -xxx -ddd
prints
-some -xxx -ddd
Just pass -- before the flags that are to go to the program, like so:
perl -e 'print join("/", #ARGV)' -- -foo bar
prints
-foo/bar
From this link: http://scala.epfl.ch/documentation/getting-started.html
#!/bin/sh
exec scala "$0" "$#"
!#
object HelloWorld extends App {
println("Hello, world!")
}
HelloWorld.main(args)
I know that $0 is for the script name, and $# for all argument passed to the execution, but what does !# means (google bash "!#" symbols seems to show no result)?
does it mean exit from script and stdin comes from remaining lines?
This is part of scala itself, not bash. Note what's happening: the exec command replaces the process with scala, which then reads the file given as "$0", i.e., the bash script file itself. Scala ignores the part between #! and !# and interprets the rest of the text as the scala program. They chose the "reverse shebang" as an appropriate counterpart to the shebang.
To see what I mean about exec replacing the process, try this simple script:
#!/bin/sh
exec ls
echo hello
It will not print "hello" since the process will be replaced by the ls process when exec is executed.
Reference: http://www.scala-lang.org/files/archive/nightly/docs-2.10.2/manual/html/scala.html
A side comment, consider multiline script,
#!/bin/sh
SOURCE="$LIB1/app.jar:$LIB2/app2.jar"
exec scala -classpath $SOURCE -savecompiled "$0" "$#"
!#
Also note -savecompiled which can speed up reexecutions notably.
is there any possibility to use haskell functions in unix shell scripts?
for instance:
#!/bin/bash
...
var1=value
...
# use haskell function with input from shell variable var1
# and store the result into another shell variable var2
var2=haskellFunction $var1
...
I want to use variables in shell scripts as arguments and results of haskell functions
Thanks in advance.
jimmy
Use the -e switch to ghc, e.g.
var2=$(ghc -e "let f x = x*x + x/2 in f $var1")
For string processing, it is best to use Haskell's interact in conjunction with bash's here strings:
var2=$(ghc -e 'interact reverse' <<<$var1)
Also, you can write scripts using ghci:
Just put shebang #!/usr/bin/env runhaskell at the first line of the script and make it executable. Such scripts may be called from sh/bash/ksh/csh/whatever scripts as usual.
E.g.
$ cat > hello.hsh
#!/usr/bin/env runhaskell
main = putStrLn "Hello world!"
$ chmod +x hello.hsh
$ ./hello.hsh
Hello world!
$
In short, I'd like to abstract this shebang so I can literally copy and paste it into other .ML files without having to specify the filename each time:
#!/usr/bin/env ocamlscript -o hello
print_endline "Hello World!"
I realize I could just drop the -o hello bit, but I'd like all the binaries to have UNIX names (hello), instead of Windows names (hello.ml.exe).
You need a complex shebang to do this. A Clojure example that has the desired behavior:
":";exec clj -m `basename $0 .clj` $0 ${1+"$#"}
":";exit
Clojure is Java-based, which is why clj needs the basename of the file (something, not something.clj). In order to get the basename, you need a multiline shebang, because a single line shebang can only handle a single, simple, static command line argument. In order to do multiline shebangs, you need a syntax which simultaneously:
Sends shell commands to the shell
Hides the shell commands from the main language
Does anyone know of OCaml trickery to do this? I've tried the following with no success:
(*
exec ocamlscript -o `basename $0 .ml` $0 ${1+"$#"}
exit
*)
let rec main = print_endline "Hello World!"
What you're looking for is a shell and Objective Caml polyglot (where the shell part invokes an ocaml interpreter to perform the real work). Here's a relatively simple one. Adapt to use ocamlscript if necessary, though I don't see the point.
#!/bin/sh
"true" = let exec _ _ _ = "-*-ocaml-*- vim:set syntax=ocaml: " in
exec "ocaml" "$0" "$#"
;;
(* OCaml code proper starts here *)
print_endline "hello"
After some trials, I found this shebang:
#!/bin/sh
"true" = let x' = "" in (*'
sh script here
*) x'
It is sort of an improvement of Gilles’ proposal, as it permits to write a full shell script inside the OCaml comment, without being bothered at all with syntax incompatibilities.
The script must terminate (eg. with exec or exit) without reaching the end of the comment, otherwise a syntax error will occur. This can be fixed easily, but it is not very useful regarding the intended use of such a trick.
Here is a variant that entails zero runtime overhead on the OCaml side, but declares a new type name (choose it arbitrarily complicated if this is bothering):
#!/bin/sh
type int' (*' >&- 2>&-
sh script here
*)
For example, here is a script that executes the OCaml code with modules Str and Unix, and can also compile it when passed the parameter --compile:
#!/bin/sh
type int' (*' >&- 2>&-
if [ "$1" = "--compile" ]; then
name="${0%.ml}"
ocamlopt -pp 'sed "1s/^#\!.*//"' \
str.cmxa unix.cmxa "$name.ml" -o "$name" \
|| exit
rm "$name".{cm*,o}
exit
else
exec ocaml str.cma unix.cma "$0" "$#"
fi
*)
I do not think that ocamlscript supports this. It may be worth submitting a feature request to the author to allow customization of the compiled binary's extension without specifying the full output basename.