Bartek Szablowski
Bartek Szablowski

Reputation: 333

Escaping linux shell arguments

I am trying to get rid of "{ }" characters in between shell arguments that have spaces in them. eg:

./cod4_start.sh hello 28960 "HOSTNAME WITH SPACES"

Once I pass "HOSTNAME WITH SPACES" as an argument, even though it's double quoted shell sees hostname as {HOSTNAME WITH SPACES}.

Is there any kind of other argument passing to the script so that I don't have { } characters in my variables ?

Here is the code:

#!/usr/bin/expect -f
set pssword [lrange $argv 0 0]
set port [lrange $argv 1 1]
set mod [lrange $argv 2 2]
set map [lrange $argv 3 3]
set num [lrange $argv 4 4]
set hostname [lrange $argv 5 5]
set rcon [lrange $argv 6 6]
set password [lrange $argv 7 7]
set gtype [lrange $argv 8 8]
set slots [lrange $argv 9 9]
spawn su - kod -c cd cod4 -c "nohup ./cod4_lnxded +set s_num=$num +set net_port $port +set dedicated 2 +set fs_game mods/$mod +set logfile 0 +set sv_punkbuster 1 +set sv_hostname \'$hostname\' +exec fastdl.cfg +set rcon_password $rcon +set g_password '$password' +set promod_mode match_mr10 +set g_gametype $gtype +set sv_maxclients $slots +set ui_maxclients $slots +map $map"  > /dev/null 2>&1 &
expect "Password:" { send "$pssword\r" }
expect "# " { send "q" }
exit

Upvotes: 1

Views: 1417

Answers (2)

TrojanName
TrojanName

Reputation: 5355

The reason you are getting curly brackets is because you are using lrange, which returns a list of elements from the input list. Instead you can use lindex which retrieves an element from a list (returned as a string).

Here's another way of getting the data:

set params_list [list pssword port mod map num hostname rcon password gtype slots ]
set i 0
foreach param $params_list {
 set $param [lindex $argv $i]
 incr i
}
puts "Map is: $map"

Upvotes: 1

bmk
bmk

Reputation: 14137

I guess you should use lindex instead of lrange in your script:

set hostname [lindex $argv 5]

Otherwise lrange will return a list with one element consisting of a string with spaces. And in TCL notation this is something like {string with spaces}.

Addendum:

As schlenk suggests you can also use lassign (depending on your TCL version)

lassign $argv pssword port mod map num hostname rcon password gtype slots

or the foreach trick:

foreach {pssword port mod map num hostname rcon password gtype slots} $argv break

Upvotes: 5

Related Questions