Forum Discussion
Blake_79204
Nimbostratus
Feb 08, 2012lassign alternative
I'm having a hard time finding documentation for this that is specific to Big-IP v 11, but it looks like iRules are based on Tcl 8.4.6. The command lassign wasn't introduced in Tcl until v8.5. This would explain why the command isn't listed in the disabled Tcl Commands list - it didn't exist.
Since I'm getting the following error, I figure either lassign really isn't supported, or I'm using it wrong:
error: line 392: [undefined procedure: lassign] [lassign $fields \ result cn goAgent goPolicyHierID goSalesID]
So, I'm hoping someone can help me devise an alternative method here:
set content [HTTP::payload]
if { $content ne "" } { log local0. "HTTP::Payload set"}
split into records in new lines
set records [split $content "\n"]
iterate over the records
foreach rec $records { split into fields on colons set fields [ split $rec ":" ]
assign fields to variables
lassign $fields \
result cn goAgent goPolicyHierID goSalesID
Any help would be appreciated.
8 Replies
- nitass
Employee
just wonder if lindex which Aaron suggested in the past discussion is not applicable.
Simple Question
http://devcentral.f5.com/Community/GroupDetails/tabid/1082223/asg/39/aft/57021/showtab/groupforums/Default.aspx - Blake_79204
Nimbostratus
It looks like that might work - lassign would have let me parse through each instance of $fields and set each as a variable with it's own name.
I think I can use lindex to select records one at a time based upon their location in the list, but I'm not clear on how to then set that record as a new variable.
For a little context - I'm trying to read an http page that has a list of strings (currently seperated by colons, but could be seperated by anything.) Then, once I have that list, I want to take each item and set it as an individual variable, which I'm then going to store and use elsewhere. So, really, I just need a decent way to read the list and store the values found there. - nitass
Employee
I'm not clear on how to then set that record as a new variable. you mean there are multiple lines in the payload and you want to keep them all, don't you? if so, may we add it into table (1 subtable per line)?
table wiki
http://devcentral.f5.com/wiki/iRules.table.ashx - nitass
Employee
e.g.[root@ve1023:Active] config b virtual bar list virtual bar { snat automap pool foo destination 172.28.19.79:80 ip protocol 6 rules myrule profiles { http {} tcp {} } } b[root@ve1023:Active] config b rule myrule list rule myrule { when RULE_INIT { set static::fields {result cn goAgent goPolicyHierID goSaleID} } when HTTP_RESPONSE { set content [string trimright [HTTP::payload] "\n"] set records [split $content "\n"] table set ntable [llength $records] for {set i 0} {$i < [llength $records]} {incr i} { set rec [lindex $records $i] set fields [split $rec ":"] for {set j 0} {$j < [llength $fields]} {incr j} { table set -subtable line$i [lindex $static::fields $j] [lindex $fields $j] } } } when HTTP_RESPONSE priority 1000 { for {set i 0} {$i < [table lookup ntable]} {incr i} { for {set j 0} {$j < [llength $static::fields]} {incr j} { log local0. "[lindex $static::fields $j]: [table lookup -subtable line$i [lindex $static::fields $j]]" } } } } [root@ve1023:Active] config curl http://172.28.19.79/test.html result1:cn1:goagent1:goplicyhierid1:gosaleid1 result2:cn2:goagent2:goplicyhierid2:gosaleid2 [root@ve1023:Active] config cat /var/log/ltm Feb 10 05:15:37 local/tmm info tmm[4822]: Rule myrule : result: result1 Feb 10 05:15:37 local/tmm info tmm[4822]: Rule myrule : cn: cn1 Feb 10 05:15:37 local/tmm info tmm[4822]: Rule myrule : goAgent: goagent1 Feb 10 05:15:37 local/tmm info tmm[4822]: Rule myrule : goPolicyHierID: goplicyhierid1 Feb 10 05:15:37 local/tmm info tmm[4822]: Rule myrule : goSaleID: gosaleid1 Feb 10 05:15:37 local/tmm info tmm[4822]: Rule myrule : result: result2 Feb 10 05:15:37 local/tmm info tmm[4822]: Rule myrule : cn: cn2 Feb 10 05:15:37 local/tmm info tmm[4822]: Rule myrule : goAgent: goagent2 Feb 10 05:15:37 local/tmm info tmm[4822]: Rule myrule : goPolicyHierID: goplicyhierid2 Feb 10 05:15:37 local/tmm info tmm[4822]: Rule myrule : goSaleID: gosaleid2 - Blake_79204
Nimbostratus
That's pretty clever - and introduces me to the trimright, table, llength, and lindex features, for which I am very grateful.
It looks like the tables are referred to as 'session tables' --- does this mean that they are persistent with the users session? - nitass
Employee
It looks like the tables are referred to as 'session tables' --- does this mean that they are persistent with the users session?yes but actually, it is globally shared data among all connection and tmm.
v10.1 - The table Command - The Basics by Spark
http://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/2375/v101--The-table-Command--The-Basics.aspx - Blake_79204
Nimbostratus
OK - changing parameters a bit here. The initial data is all on one line, with key/value pairs seperated like this:
cn=JoeAgent | Intradoc_Hrchy_Tx=somevalue | first_nm=Joe | last_nm=Agent | de3fault_agnt_id=123fake | EMAIL_ADR=agentjoe@fake.org
The keys and variables may change without notification - so hardcoding them in as a static::field is less than ideal. The initial data is already stored as a variable (let's say it's $attributes).
We can split the $attributes into records based on "|", and then split the records into fields based upon "=".
Where I'm getting stumped is populating a table with those fields. How do I get it to look something like this:
key | value
$field1 | $field2
$field3 | $field4 etc.
I can then pull the data from the table, because I'll know the key name that I'm looking for when I need to pull it back from the table- so I can do a
table lookup $field3
for example, substituting the value of $field3 and getting the $field4 value returned.
Any help would be appreciated. - Blake_79204
Nimbostratus
Maybe this?
set fields [split $ag_attributes "|"]
for {set i 0} {$i < llength $fields} {incr i} {
scan $fields {%[^=]=%s} $key $attribute
set table -subtable attributes $key $attribute
THEN LATER, TO RECALL DATA:
table lookup -subtable attributes <$key>
(input actual value of $key instead of $key)
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
