Reputation: 16428
I came across this scenario, where I have to execute tshark
for decoding the pcap
file.
Location of of tshark is C:\Program Files\Wireshark\tshark.exe
% set fileName TestTShark.pcap
TestTShark.pcap
% set sTsharkCmd "-r $fileName -Tfields -e ip.src"
-r TestTShark.pcap -Tfields -e ip.src
% set tsharkPath "C:/Program Files/Wireshark/tshark.exe"
C:/Program Files/Wireshark/tshark.exe
% eval exec $tsharkPath $sTsharkCmd > packet.log
couldn't execute "C:\Program": no such file or directory
% exec $tsharkPath $sTsharkCmd > packet.log
tshark: The file " TestTShark.pcap -Tfields -e ip.src" doesn't exist.
% set tsharkPath "C:\\Program Files\\Wireshark\\tshark.exe"
C:\Program Files\Wireshark\tshark.exe
% exec $tsharkPath $sTsharkCmd > packet.log
tshark: The file " TestTShark.pcap -Tfields -e ip.src" doesn't exist.
% eval exec $tsharkPath $sTsharkCmd > packet.log
couldn't execute "C:Program": no such file or directory
Since the path containing a space, while evaluating the code, Tcl
treating C:\Program
as a program name and throwing the error. Then I managed to escape the space with backslash as follows, which worked then.
% set tsharkPath "C:/Program\\ Files/Wireshark/tshark.exe"
C:/Program\ Files/Wireshark/tshark.exe
% eval exec $tsharkPath $sTsharkCmd > packet.log
% type packet.log
20.0.0.5
%
I am just curious. Is there any other option to handle this scenario ? Same problem observed with {*}
also.
Upvotes: 1
Views: 1028
Reputation: 137567
Your problem is that you're wanting space to be a part of an argument taken from variable, but to separate arguments coming from another argument. Tcl by default will try to apply the same uniform rules to all arguments: you need to do something extra to change that.
You want to use expansion of an argument. Your command
% eval exec $tsharkPath $sTsharkCmd > packet.log
Should be written as:
% exec $tsharkPath {*}$sTsharkCmd > packet.log
See how it is shorter? It's safer too. Try to avoid eval
unless you really are doing something very complicated. (I hardly ever need it in my code…)
If you're stuck with an ancient version of Tcl without {*}
, you need to do this instead:
% eval [linsert $sTsharkCmd 0 exec $tsharkPath > packet.log]
Which is horribly non-obvious, or this:
% eval {exec $tsharkPath} $sTsharkCmd {> packet.log}
Which isn't too nice either (and it's easy to forget to get it quoted right).
Upvotes: 2
Reputation: 2218
eval [list exec $tsharkPath {*}$sTsharkCmd]
Make the new command to evaluate with the sTsharkCmd
attributes separated...
Upvotes: 1