skarnet / execline

The execline scripting language
https://skarnet.org/software/execline/
ISC License
149 stars 19 forks source link

Argument Generation #11

Closed kyzima-spb closed 2 years ago

kyzima-spb commented 2 years ago

Good day.

Is it possible to create a "variable" with a generated name and argument value, and then use this "variable" when calling a command?

I give a demo example, where I removed all unnecessary, leaving only the essence of the issue:

define password_file "/root/.vncpswd"

backtick !
{
    ifelse { test -s "$password_file" }
    {
        echo "-rfbauth ${password_file}"
    }
    echo "-nopw"
}
importas -u password_arg !

/usr/bin/x11vnc $password_arg

If the file does not exist or is empty, there are no errors. If the file exists and is not empty - error:

unrecognized option(s)
-rfbauth /root/.vncpswd

This is similar to the behavior in Shell if the variable is specified in double quotes:

/usr/bin/x11vnc "$password_arg"
skarnet commented 2 years ago

You want to create two words, -rfbauth and /root/.vncpswd, from one string substitution. This is dangerous (it's the source of a lot of bugs in shell scripts), so execline doesn't do it by default. When you want to split words during a substitution, you have to do it explicitly: add the -s option to the importas command.

As a side note, you probably should not use echo to print strings that begin with -; depending on the implementation of your echo command, this may or may not be interpreted as an option. When in doubt, use s6-echo -- instead of echo, and you will make sure your strings will be printed verbatim.

Also, I will show you a simpler way to write your script excerpt that avoids using backtick, echo and importas. You can use it, but please do not make a habit out of it because ifthenelse -s is very dirty - it goes against the execline logic, and the option only exists because it's convenient in cases like yours.

define password_file "/root/.vncpswd"
ifthenelse -s { test -s "$password_file" }
{ define -s password_arg "-rfbauth ${password_file}" }
{ define -s password_arg "-nopw" }
/usr/bin/x11vnc "$password_arg"
kyzima-spb commented 2 years ago

Thank you very much for the detailed answer and for the code review.

I tried to create a "variable" in this way with different conditional instructions =) But I didn't know about the dirty hack, I saw that this option was not documented =)