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

Pass an array as a command line argument to a tcl script

1,604 views
Skip to first unread message

Sooraj S

unread,
Dec 8, 2010, 4:21:09 AM12/8/10
to
Hi,

I have perl program which internally calls an expect script to
download some files from an ftp server.

Is it possible to pass an array as a command line option to the expect
script?

Pls help me.

Donal K. Fellows

unread,
Dec 8, 2010, 8:33:28 AM12/8/10
to

Values can normally[*] only be passed between programs as strings, so
you'll need to convert your array to a sequence of one or more
argument strings that are parsed by expect script. There are many
tools in Tcl (and hence in Expect) for parsing strings; argument
strings are kept in the global $argv variable (as a Tcl list; use
[lindex] to get a particular one or [foreach] to iterate over all of
them). The only character that can't be passed that way is a NUL byte,
as that's reserved for use by the OS (as a string terminator).

Without knowing exactly how you're converting the array to a string on
the Perl side, it's hard to advise how to unpack things on the Tcl/
Expect side. Show some code and/or an example of the sort of string
that gets passed, and we'll be able to tell you exactly what to do.

Donal.
[* In the non-normal case, there's serialization libraries. This is a
complex area, and possibly overkill for this case. ]

Glenn Jackman

unread,
Dec 8, 2010, 10:21:03 AM12/8/10
to

Is this a Perl array or a Tcl array. A Perl array is like a Tcl list
and a Tcl array is like a Perl hash.

Both Tcl and Perl have JSON packages, so you might want to create a JSON
string from your Perl data structure, and pass that to Expect.

--
Glenn Jackman
Write a wise saying and your name will live forever. -- Anonymous

Sooraj S

unread,
Dec 8, 2010, 11:18:49 AM12/8/10
to

Hi,

Thanks for your reply .But is there any way to do this without using
any external packages?

In my perl progrom i am passing 6 arguments to the expect script.

system($expect_script $val1 $val2 @val3 @val4 @val5 $val6)

As you can see, there are 3 arrays val3,val4 and val5 whose size is
not static.

How can my expect script can access those arrays?

Gerald W. Lester

unread,
Dec 8, 2010, 1:02:54 PM12/8/10
to

lassign $argv val1 val2 val3List val4List val5List val6

You then use [lindex $val3List $index] to access an element, indexes start at 0.

--
+------------------------------------------------------------------------+
| Gerald W. Lester, President, KNG Consulting LLC |
| Email: Gerald...@kng-consulting.net |
+------------------------------------------------------------------------+

Sooraj S

unread,
Dec 9, 2010, 3:42:26 AM12/9/10
to
On Dec 8, 11:02 pm, "Gerald W. Lester" <Gerald.Les...@KnG-
> | Email: Gerald.Les...@kng-consulting.net                                |
> +------------------------------------------------------------------------+- Hide quoted text -
>
> - Show quoted text -

Hi,

I tried using lassign in my expect script. But it errors out like this
-
"invalid command name "lassign"

Donal K. Fellows

unread,
Dec 9, 2010, 4:12:49 AM12/9/10
to
On Dec 9, 8:42 am, Sooraj S <soorajspadmanab...@gmail.com> wrote:
> I tried using lassign in my expect script. But it errors out like this
> -
> "invalid command name "lassign"

Your version of expect must be built against an old version of Tcl.
That sucks. Here's a workaround which you should put near the top of
your script:

if {![llength [info commands lassign]]} {
proc lassign {list args} {
foreach var $args {
upvar 1 $var v
set v [lindex $list 0]
set list [lrange $list 1 end]
}
return $list
}
}

(That's pretty much what real [lassign] does, but the real one's a bit
more efficient. :-))

Donal.

Uwe Klein

unread,
Dec 9, 2010, 4:06:00 AM12/9/10
to
Sooraj S wrote:
>>| Gerald W. Lester, President, KNG Consulting LLC |

>>lassign $argv val1 val2 val3List val4List val5List val6


>>
>>You then use [lindex $val3List $index] to access an element, indexes start at 0.

>

> I tried using lassign in my expect script. But it errors out like this
> -
> "invalid command name "lassign"

What version of tcl are you using. ( lassign is a reasonably new addition )


replace with

foreach {val1 val2 val3List val4List val5List val6} $argv break

which is functionally equivalent.

uwe

>

Sooraj S

unread,
Dec 9, 2010, 4:41:47 AM12/9/10
to
On Dec 9, 2:12 pm, "Donal K. Fellows"

Hi,

Thanks for your help. Now it doesnot error out. But the arrays passed
from perl script are not accepted as itself in the expect program..it
splits the array into elements.


in perl script :=> system($expect_script $val1 $val2 @val3 @val4 @val5
$val6)

@val3 contains 3 elements : hello, hai, alas

My expect script
=================
#!/usr/bin/expect -f

if {![llength [info commands lassign]]} {
proc lassign {list args} {
foreach var $args {
upvar 1 $var v
set v [lindex $list 0]
set list [lrange $list 1 end]
}
return $list
}
}

lassign $argv val1 val2 val3List val4List val5List val6

foreach data $val3List {
puts "\nCheck : $data";
}

O/p => Check : hello

It does not print the rest of the elements.

Glenn Jackman

unread,
Dec 9, 2010, 5:27:35 AM12/9/10
to

Thst Perl command will flatten all your arrays into one long list of
elements. If you don't want to use common and well-tested external
packages, you'll have to roll your own.

Depending on the contents of your data, you can do something like this:

# perl
system $expect_script, $val1,
$val2,
join(':', @val3),
join(':', @val4),
join(':', @val5),
$val6;

# expect
set val1 [lindex $argv 0]
set val2 [lindex $argv 1]
set val3 [split [lindex $argv 2] :]
set val4 [split [lindex $argv 3] :]
set val5 [split [lindex $argv 4] :]
set val6 [lindex $argv 5]

Gerald W. Lester

unread,
Dec 9, 2010, 8:17:14 AM12/9/10
to

What is in val4List?

At this point it is a perl problem with either not passing all of the array
or doing strange magic and spliting it up into different args.

--
+------------------------------------------------------------------------+
| Gerald W. Lester, President, KNG Consulting LLC |

| Email: Gerald...@kng-consulting.net |
+------------------------------------------------------------------------+

Nagesh HS

unread,
Jul 5, 2017, 11:59:13 PM7/5/17
to
Hi Donal,
The method you mentioned, will help to pass multiple arrays to script, In my script I am trying to pass 4 arrays to the script .

tclsh myscript.tcl arr1 arr2 arr3 arr4

How to pass multiple array to scripts.

Matthew Hiles

unread,
Jul 8, 2017, 9:47:32 AM7/8/17
to
You can shoe-horn arrays into values that can be parsed on as command line arguments, but it's not going to scale well--not sure exactly how big your perl arrays are.

I'd suggest writing a perl sub that converts your perl arrays into a well-formatted tcl lists and pass that through stdin to your tcl program.


Sounds like you're stuck working on an old system that you can't add or update software--something like json or yml would make this smoother going.

0 new messages