Clozure CL compiled executable losing certain command line arguments - common-lisp

I'm writing a utility program in Common Lisp and building it with Clozure CL; I would like to be able to use the command-line option -d with the program, but for some reason this particular option won't make it through to (ccl::command-line-arguments). Here is a minimal example:
(defun main ()
(format t "~s~%" (ccl::command-line-arguments))
(quit))
I compiled with
(save-application "opts"
:toplevel-function 'main
:prepend-kernel t)
and here's some sample output:
~/dev/scratch$ ./opts -c -a -e
("./opts" "-c" "-a" "-e")
~/dev/scratch$ ./opts -c -d -e
("./opts" "-c" "-e")
~/dev/scratch$ ./opts -b --frogs -c -d -e -f -g -h --eye --jay -k -l
("./opts" "--frogs" "-c" "-e" "-f" "-g" "-h" "--eye" "--jay" "-k" "-l")
The -b and -d options appear to be getting lost. The documentation on command line arguments for ccl isn't very helpful. I thought maybe because ccl itself takes -b as an argument, that option might have gotten eaten for some reason, but it doesn't take -d (which is eaten), and it does take -e and -l which aren't. Nothing on saving applications seemed helpful.
I'm pretty sure it's Clozure-specific (and not, say, the shell eating them), because other stuff seems to be getting all the arguments:
#!/usr/bin/python
import sys
print sys.argv
yields
~/dev/scratch$ ./opts.py -a -b -c -d -e
['./opts.py', '-a', '-b', '-c', '-d', '-e']
and
#!/bin/bash
echo "$#"
gives
~/dev/scratch$ ./opts.sh -a -b -c -d -e
-a -b -c -d -e
This is all taking place on lubuntu 15.10 with bash as the shell.
If anyone could shed some light on why this is happening or how I can end up with all my command-line switches, I'd be appreciative.
Thanks.

According to the source code of the 1.11 release, -b and -d are options used by the lisp kernel.
Since I'm unsure about licence issues, I just provide the link to the relevant file: http://svn.clozure.com/publicsvn/openmcl/release/1.11/source/lisp-kernel/pmcl-kernel.c
Command line arguments are processed in the function process_options, where for options -b (--batch) and -d (--debug) - among others - a variable num_elide is set to 1. A bit further down, this leads to overwriting the option with the following argument (argv[k] = argv[j];).
The code also shows a possible fix: Supply -- (two dashes) once as argument before -b or -d. When above function encounters a -- it stops processing the rest of the arguments, thus leaving them unchanged to be possibly taken up into "lisp world" shortly after.
Turns out this has already been solved at SO before:
https://stackoverflow.com/a/5522169/1116364

Related

How to print unix tool version in BusyBox container?

I can't figure out how to print (unix tool) versions within a BusyBox container:
$ docker run -it quay.io/quay/busybox:latest
$ awk --version
awk: unrecognized option `--version'
BusyBox v1.32.0 (2020-08-31 17:40:13 UTC) multi-call binary.
Usage: awk [OPTIONS] [AWK_PROGRAM] [FILE]...
-v VAR=VAL Set variable
-F SEP Use SEP as field separator
-f FILE Read program from FILE
-e AWK_PROGRAM
$ cut --version
cut: unrecognized option `--version'
BusyBox v1.32.0 (2020-08-31 17:40:13 UTC) multi-call binary.
Usage: cut [OPTIONS] [FILE]...
Print selected fields from each input FILE to stdout
-b LIST Output only bytes from LIST
-c LIST Output only characters from LIST
-d CHAR Use CHAR instead of tab as the field delimiter
-s Output only the lines containing delimiter
-f N Print only these fields
-n Ignored
Any suggestions? Many mulled containers are built on top of BusyBox, best I get on top of this.
Thanks
busybox is a single program which acts as one of various tools depending on what name was used to call it. As you can see in the question, it shows its version as BusyBox v1.32.0.
Check which tools are (symbolic) links to busybox. All these are the same program and therefore have the same version, so you might only need the version of busybox and a list of commands linked to it.
According to https://unix.stackexchange.com/q/15895/330217 the best way to display the version of busybox is
busybox | head -1

How to use GNU parallel with ::: in the middle of the command

I would like to use GNU parallel to run a command for multiple systems.
The command would be:
nimadm -c <system> -l lppsource73 -s spot73 -o bosinst_migration -j nimadm_vg -d hdisk0 -Y
for I have a list of systems in a variable.
I tried following in parallel:
parallel nimadm -c ::: $HOSTS -l lppsource73 -s spot73 -o bosinst_migration_73 -j nimadm_vg -d hdisk0 -Y
Unfortunately it is not working... parallel starts a job for everything after the ":::"
Can you help me please?
Thanks in advance...
best regards,
Joerg
parallel nimadm -c {} -l lppsource73 -s spot73 -o bosinst_migration -j nimadm_vg -d hdisk0 -Y ::: $HOSTS
This is covered in:
the cheatsheet https://www.gnu.org/software/parallel/parallel_cheat.pdf
the book https://www.lulu.com/shop/ole-tange/gnu-parallel-2018/paperback/product-23558902.html or download it at: https://doi.org/10.5281/zenodo.1146014 Read at least chapter 1+2. It should take you less than 20 minutes.
the intro videos: https://youtube.com/playlist?list=PL284C9FF2488BC6D1
If you want to dive deeper: spend a couple of hours walking through the tutorial (man parallel_tutorial). Your command line will love you for it.
You can also find a lot of examples of use in man parallel_examples.

redirect from output file so can be captured

A program foo writes to an output file and prints diagnostic information to stdout.
Thus:
foo -o ./out -i ./input > log
results in the valuable stuff in ./out and some mumbo jumbo in log.
I need to read ./out into another program (an R script I am writing).
The intermediate step of writing to file ./out and reading again is slow, and I need to do this for big ./out files, hundreds of times.
I would like to perform some kind of redirection so that foo writes to a file descriptor rather than a file ./out, which I can read into my script directly. But stdout is already used.
Here is what I tried:
in R:
library(data.table)
fread(cmd = "foo -o /dev/stdout -i ./input > /dev/null")
but I get an error:
File '/data1/tmp/RtmpkKIpBm/fileeb789130da8e3' has size 0. Returning a NULL data.table.
foo -o >(cat) -i ./input > log
Demo:
$ cat foo
#!/bin/bash
if [ "$1" != "-o" ]; then
exit 2
fi
echo "mumbo jumbo stdout" >&1
echo "valueable info" > "$2"
echo "mumbo jumbo stderr" >&2 # threw in stderr for good measure
$ ./foo -o x
mumbo jumbo stdout
mumbo jumbo stderr
$ cat x
valueable info
$ rm x
$ ./foo -o /dev/stdout
mumbo jumbo stdout
valueable info
mumbo jumbo stderr
$ ./foo -o /dev/stdout &>/dev/null
$ ./foo -o >(cat) &>/dev/null
valueable info
Explanation:
Every process has its own stdout. with ./foo -o /dev/stdout &>/dev/null, you're telling foo to output its valuable info into its own stdout, which is /dev/null. But with ./foo -o >(cat) &>/dev/null, you're telling foo to output its valuable info into some pipe, and that pipe goes to cat, whose stdout is not /dev/null, but rather inherited from the shell.
In the demo, the shell's stdout is the terminal, but if it was coming from R's fread(), both the shell's stdout and cat's stdout would go to where fread() can read them.
Try
foo -o /dev/fd/3 -i ./input 3>&1 1>/dev/null
Redirections are processed before commands are run
Redirections are processed left-to-right
3>&1 causes anything written to file descriptor 3 to go to the current stdout
1>/dev/null causes anything written to stdout to go to /dev/null
Writing to /dev/fd/3 then writes to the original stdout
The code should work with any POSIX-compliant shell on any system that supports the /dev/fd directory.
The /dev/fd directory is not part of POSIX, but it is supported on many Unix-like systems, including Linux, FreeBSD, macOS, and Solaris.

What's the difference between -a and -e in a zsh conditional expression?

I was looking up the meaning of flags like -a in zsh if statements, eg.
if [[ -a file.txt ]]; do
# do something
fi
and I found this
-a file
true if file exists.
-e file
true if file exists.
What is the difference between -a and -e? And if there is none, why do they both exist?
POSIX sheds some light on this.
tl;dr: Ksh traditionally used -a and several other shells followed suit. POSIX instead borrowed -e from Csh to avoid confusion. Now many shells support both.
The -e primary, possessing similar functionality to that provided by the C shell, was added because it provides the only way for a shell script to find out if a file exists without trying to open the file. Since implementations are allowed to add additional file types, a portable script cannot use:
test -b foo -o -c foo -o -d foo -o -f foo -o -p foo
to find out if foo is an existing file. On historical BSD systems, the existence of a file could be determined by:
test -f foo -o -d foo
but there was no easy way to determine that an existing file was a regular file. An early proposal used the KornShell -a primary (with the same meaning), but this was changed to -e because there were concerns about the high probability of humans confusing the -a primary with the -a binary operator.

How to redirect Dtrace output when using the -c flag?

How can I redirect only Dtrace's output when running a script with the -C flag?
like in this case:
dscript.d -s myscript.d -c date
Note: I found the answer to my question before posting it, but I'm putting it here so it's part of SO.
One solution with pipes is:
dtrace -o /dev/fd/3 -s dscript.d -c date 3>&1 1>out 2>err
which says:
dtrace's stdout goes to fd 3, which is dup'd from the current stdout
dtrace's stderr goes to 'err'
date's stdout is modified to 'out'
date's stderr is modified to 'err'
Or the more simpler method is to do:
dtrace -o log.txt -s dscript.d -c date

Resources