简体   繁体   中英

Using eval exec with an executable name containing spaces in the path

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.

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).

eval [list exec $tsharkPath {*}$sTsharkCmd]

使用sTsharkCmd属性分隔的新命令进行评估...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM