Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to pass variables to another tcl script?

1,427 views
Skip to first unread message

sid....@gmail.com

unread,
Apr 24, 2008, 5:02:32 AM4/24/08
to
Hello all,

Here is my problem:
I want to be able to pass variables to another tcl script from my
software.
Code, for the first script, is:

catch [exec bltwish lic.tcl $arg] secretkey

and code for lic.tcl is:

package require md5
md5::hmac -hex - key XXXXXXXX $arg

Of course, it doesn't work.
It tells me: Error in startup script: can't read "arg": no such
variable

How can I do that kind of thing?
And once it will work, I would be able to make a binary of lic.tcl to
hide for users the key XXXXXX: is it possible? (with starkit for
example)
Thanks in advance!
alex

sleb...@gmail.com

unread,
Apr 24, 2008, 6:05:34 AM4/24/08
to
On Apr 24, 5:02 pm, sid.va...@gmail.com wrote:
> Hello all,
>
> Here is my problem:
> I want to be able to pass variables to another tcl script from my
> software.
> Code, for the first script, is:
>
> catch [exec bltwish lic.tcl $arg] secretkey
>
> and code for lic.tcl is:
>
> package require md5
> md5::hmac -hex - key XXXXXXXX $arg
>
> Of course, it doesn't work.
> It tells me: Error in startup script: can't read "arg": no such
> variable

It works in a similar manner to C/C++ if you are familiar with C:
$argv is a list of all command line parameters and $argc tells you how
many command line parameters there are. So change lic.tcl to:

package require md5
md5::hmac -hex - key XXXXXXXX [lindex $argv 0]

alex

unread,
Apr 24, 2008, 7:27:45 AM4/24/08
to
> It works in a similar manner to C/C++ if you are familiar with C:
> $argv is a list of all command line parameters and $argc tells you how
> many command line parameters there are. So change lic.tcl to:
>
> package require md5
> md5::hmac -hex - key XXXXXXXX [lindex $argv 0]

Thank you very much, I'm not familiar with C, so your answer is
useful.
Unfortunatly, it doesn't work even if I replace [lindex $argv 0]
directly by the value of my variable.
I think the problem is the "catch" command in my first script.
Is it correct to think that the catch command will set the variable
"secretkey" with the result of lic.tcl??
remember my command:


catch [exec bltwish lic.tcl $arg] secretkey

When debugging, it seams that $secretkey is empty...
What's wrong?

Ron Fox

unread,
Apr 24, 2008, 7:59:34 AM4/24/08
to
catch returns the value of 0 if the command succeded or 1 if it failed.
the final parameter is either the result of the command attempted if
successful or any error message if it failed

Catch takes only two parameters

Typical use of catch in this case might be:

if {[catch {exec bltwish lic.tcl $arg} secretkey]} {
puts "Error executing bltwish $secretkey
} else {
# do whatever you want to do if the command succeeded
}

Note that
doing

catch [exec bltwish lic.cl $arg] secretkey

does not do what you probably want. It does the exec and then
substitutes the output of the exec for the command catch attempts to
execute.

RF.

alex

unread,
Apr 24, 2008, 8:25:22 AM4/24/08
to
On 24 avr, 13:59, Ron Fox <f...@nscl.msu.edu> wrote:
> catch returns the value of 0 if the command succeded or 1 if it failed.
> the final parameter is either the result of the command attempted if
> successful or any error message if it failed
>
> Catch takes only two parameters
>
> Typical use of catch in this case might be:
>
> if {[catch {exec bltwish lic.tcl $arg} secretkey]} {
> puts "Error executing bltwish $secretkey} else {
>
> # do whatever you want to do if the command succeeded
>
> }
>
> Note that
> doing
>
> catch [exec bltwish lic.cl $arg] secretkey
>
> does not do what you probably want. It does the exec and then
> substitutes the output of the exec for the command catch attempts to
> execute.
>
> RF.
>

OK, thank you. I seams that i'm also not familiar with tcl!! ;)
So, have you any idea on how I can do what I need: put in the variable
secretkey the results from the exec lic.tcl and use it in my first
script? (return the result)

Bryan Oakley

unread,
Apr 24, 2008, 9:35:19 AM4/24/08
to
Ron Fox wrote:
> catch returns the value of 0 if the command succeded or 1 if it failed.

Not entirely correct. It will return 0 if the command succeeded, but it
can return several different non-zero values depending on the return code.

For example:

(bin) 49 % catch {return "foo"}
2

Glenn Jackman

unread,
Apr 24, 2008, 9:39:29 AM4/24/08
to

When you [exec] a process, you can only get results back from it by
stdio channels.

lic.tcl:
package require md5
set arg [lindex $argv 0]
puts [md5::hmac -hex - key XXXXXXXX $arg]

in first script (note the change in quoting in the catch command):

if {[catch {exec bltwish lic.tcl $arg} secretkey] != 0} {
error "some error: $secretkey"
}

If you need to "include" a tcl script from within a tcl script, [source]
is the command you want

in first script:
set arg foobar
source lic.tcl
puts "my secret key is: $secretkey"

in lic.tcl
package require md5
set secretkey [md5::hmac -hex - key XXXXXXXX $arg]

That doesn't address the obfuscation of lic.tcl. Use a starkit
to compile lic.tcl to lic.exe (http://www.equi4.com/starkit/) and then
use the first strategy above.

--
Glenn Jackman
"If there is anything the nonconformist hates worse than a conformist,
it's another nonconformist who doesn't conform to the prevailing
standard of nonconformity." -- Bill Vaughan

alex

unread,
Apr 24, 2008, 9:45:28 AM4/24/08
to

It's OK, by inserting, in my lic.tcl:
---------------------8<--------------------------
set result [md5::hmac -hex - key XXXXXXXX [lindex $argv 0]]
puts $result
---------------------8<--------------------------

and inserting in my main script:
---------------------8<--------------------------
set secretkey [exec bltwish lic.tcl $arg]
---------------------8<--------------------------

Now, I have wrapped my lic.tcl script with starkit (it produce the
file "lic") and....it doesn't work no more...!
---------------------8<--------------------------
set secretkey [exec lic $arg]
---------------------8<--------------------------
it returns: couldn't find arg : No such file.

What's wrong ?? How can I pass my variable to the lic script?

suchenwi

unread,
Apr 24, 2008, 9:50:37 AM4/24/08
to
> What's wrong ?? How can I pass my variable to the lic script?- Zitierten Text ausblenden -

[exec] runs an executable. "lic" probably isn't one, and maybe it
isn't even copied outside the starkit.
I'd expect better chances if you
- copy lic.tcl out to the real filesystem (not the virtual one inside
the starkit),
- do: exec tclsh lic.tcl $arg

But maybe you can do all that action in a single process, which would
make things much easier...

alex

unread,
Apr 24, 2008, 10:33:48 AM4/24/08
to

> [exec] runs an executable. "lic" probably isn't one, and maybe it
> isn't even copied outside the starkit.
> I'd expect better chances if you
> - copy lic.tcl out to the real filesystem (not the virtual one inside
> the starkit),
> - do: exec tclsh lic.tcl $arg
>
> But maybe you can do all that action in a single process, which would
> make things much easier...

My "lic" file is the results from a starkit. So it's an executable.
It the results of compiling my lic.tcl file (which works fine with my
exec command) with starkit.

Initial content of main file (works fine):


---------------------8<--------------------------
set secretkey [exec bltwish lic.tcl $arg]
---------------------8<--------------------------

Replaced by (after compiling with starkit):


---------------------8<--------------------------
set secretkey [exec lic $arg]
---------------------8<--------------------------

It seams that with this kind of executable, i was no longer able to
pass my arg to the compiled script.

Content of my lic.tcl file (works fine):

alex

unread,
Apr 24, 2008, 11:46:46 AM4/24/08
to
After debugging my own code, here are my conclusion:
It's not possible to pass any argument to a starpack!

It's the reason why:
set secretkey [exec bltwish lic.tcl $arg] works whereas:
set secretkey [exec lic $arg] doesn't!

Am I wrong or not?
Is there a way to do so?

Bryan Oakley

unread,
Apr 24, 2008, 12:51:14 PM4/24/08
to

I think you are wrong. You definitely can pass arguments to starpacks.

When you say it doesn't work, what do you mean? Are you getting a tcl
error? Are you getting some other type of error? Have you proven that
you are properly wrapping the code? That is, if you hard-code the
argument and create an executable, does it then work? How do you know
the problem is in the passing of arguments rather than in something else?

Is it possible that your code inside lic has forgotton to declare argv
as global?

Perhaps the best solution is to start with creating a simple starkit and
see if you can exec that. Then, modify your starkit script to print out
argv. Finally, compare that working version to what you did with your
program to see how they are different.

For lack of a better option, try the example here:
http://coding.derkeiler.com/Archive/Tcl/comp.lang.tcl/2004-05/0254.html


Andreas Leitgeb

unread,
Apr 25, 2008, 4:00:07 AM4/25/08
to
alex <sid....@gmail.com> wrote:
> After debugging my own code, here are my conclusion:
> It's not possible to pass any argument to a starpack!
> It's the reason why:
> set secretkey [exec bltwish lic.tcl $arg] works whereas:
> set secretkey [exec lic $arg] doesn't!

Since you omitted the .tcl in the second version, I assume
that you're on windows, and you have some system binding
for .tcl that doesn't propagate the arguments...

But that's just speculation.

alex

unread,
Apr 25, 2008, 8:07:58 AM4/25/08
to
> I think you are wrong. You definitely can pass arguments to starpacks.

OK, that's the good news!

>
> When you say it doesn't work, what do you mean? Are you getting a tcl
> error? Are you getting some other type of error? Have you proven that

Yes, I'm getting an error, as explain in a previous message.
Before compiling, if I do:
bltwish lic.tcl toto -> I get a valid answer. That's OK
after compiling, if I do (even if I'm on linux, to clarify, I'll call
my compiled script lic.exe):
lic.exe toto -> it produce an error: couldn't read toto: no such file
or directory
If I do:
lic.exe -> it produce the same answer as if I do: bltwish lic.tcl
So, it seems that my lic.exe is ok and doesn't accept the argument
"toto".
Am I clear?

> you are properly wrapping the code? That is, if you hard-code the
> argument and create an executable, does it then work? How do you know
> the problem is in the passing of arguments rather than in something else?
>

I have already done this and it works.

> Is it possible that your code inside lic has forgotton to declare argv
> as global?
>
> Perhaps the best solution is to start with creating a simple starkit and
> see if you can exec that. Then, modify your starkit script to print out
> argv. Finally, compare that working version to what you did with your
> program to see how they are different.
>

My script lic.tcl is already a simple script.
The whole content is:
---------------------8<--------------------------
#!/UTIL/bltwish
global argv
package require md5
set secretkey [md5::hmac -hex -key XXXXXXXX [lindex $argv 0]]
puts $secretkey
exit
---------------------8<--------------------------

alex

unread,
Apr 25, 2008, 8:09:59 AM4/25/08
to
On 25 avr, 10:00, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
wrote:

No, I'm on Linux.
"lic", without extension is my compiled version of my lic.tcl script.

vit...@gmail.com

unread,
Apr 25, 2008, 4:42:27 PM4/25/08
to
Try wrapping your script in a different way:

#create a copy of tclkit to wrap
#together with the lic.tcl script

[ cp tclkit-linux-x86 tclkit-linux-x86_runtime ]

#create a directory lic.vfs

[ mkdir lic.vfs ]

#add this to the top
#of your lic.tcl file

____________________________________________
package require starkit
if {[starkit::startup] == "sourced"} return
____________________________________________

#copy the lic.tcl file
#into lic.vfs/ dir
#and rename it main.tcl

[ cp lic.tcl lic.vfs/main.tcl ]

#wrap it

[ tclkit-linux-x86 sdx.kit wrap lic -runtime tclkit-linux-
x86_runtime ]

#You will get a single lic.kit executable.

[ lic.kit $arg ]

Should work just fine, works for me.
You might have problems with some tclkits. This one worked for me:

http://www.equi4.com/pub/tk/8.5.1/tclkit-linux-x86.gz

Also, in your main/calling script you might need to do

[ subst -nocommands {exec lic.kit $arg} ]

This will replace your $arg with the value of the $arg before it gets
passed to the lic.kit command.

Hope some of that helps.

---Victor


alex

unread,
Apr 28, 2008, 8:14:29 AM4/28/08
to

OK, thank you very much!
I've done as Victor explains and it works fine.
alex

vitic

unread,
Apr 28, 2008, 1:36:28 PM4/28/08
to

I am glad it helped you.

---Victor

0 new messages