I am using TCL to control a traffic generator. When the traffic received, I want to use shark command to convert the .pcap file to a .txt file, and then I can do some other job.
But when run the exec in the program the following info print out:
while executing
"exec tshark -Vxr /var/tmp/PCRF/create_req.pcap"
("eval" body line 1)
invoked from within
"eval exec {tshark -Vxr /var/tmp/PCRF/create_req.pcap}"
(file "./tcp_test.tcl" line 7)
The following is the TCL script:
# Radius accounting request start packets
# Version 1.0
# Date 2014/4/16 16:38
puts "\n Begin to decode the capture file\n"
#source /var/tmp/PCRF/convert_pcap.tcl
eval exec {tshark -Vxr /var/tmp/PCRF/create_req.pcap}
puts "\n end of the file decode and the result is rrr\n"
Tcl's exec can throw an error for two reasons. It does so if either:
The subprocess returns a non-zero exit code.
The subprocess writes to standard error.
The first one can be annoying, but it is genuinely how programs are supposed to indicate real errors. It can be a problem if the program also uses it in other ways (e.g., to say that nothing was found, like grep does) but that. However, in this case you get the error message child process exited abnormally so it is easy to at least figure out what happened.
More problematic is when something is written to standard error; the message written there is used as the error message after newline stripping. Even just a newline will trigger a failure, and that failure overwrites any chance of getting the real out from the program (and in the case of just a newline, is highly mysterious). Here's a (possibly) reproduction of your problem:
% exec /bin/sh -c {echo >&2}
% set errorInfo
while executing
"exec /bin/sh -c {echo >&2}"
How to fix this? Well, you can try the -ignorestderr option (if supported by your version of Tcl, which you don't mention):
exec -ignorestderr tshark -Vxr /var/tmp/PCRF/create_req.pcap
Or you can try merging the standard output and standard error channels with 2>#1, so that the error messages are part of the overall output stream (and picked up as a normal result):
exec tshark -Vxr /var/tmp/PCRF/create_req.pcap 2>#1
Or you could use a merge-pipe (needed for older Tcl versions):
exec tshark -Vxr /var/tmp/PCRF/create_req.pcap |& cat
Or you can even direct the subprocess's standard error to the main standard error: the user (or exterior logger) will see the “error” output, but Tcl won't (and the exec won't fail):
exec tshark -Vxr /var/tmp/PCRF/create_req.pcap 2>#stderr
More elaborate things are possible with Tcl 8.6, which can make OS pipes with chan pipe, and you can (in all Tcl versions) run subprocesses as pipelines with open |… but these are probably overkill.
You don't need eval exec {stuff…}; plain old exec stuff… is precisely equivalent, shorter to write and a bit easier to get correct.
Related
Here is the error message:
May 10, 2021 4:01:35 PM com.altera.debug.core
SEVERE: java.lang.Exception: invalid command name "exit"
while executing
"exit
"
invoked from within
"if {$use_specified_base_addresses == 1} {
puts "using predefined peripheral base addresses"
# Peripheral address offset from taken from ..."
It is strange that the keyword "exit" is not being identified by the interpreter I am using. I just need to stop running the script when "catch" actually catches error raised by a procedure call. I am getting this problem in Quartus Prime Standard System Console.
The exit command is a standard Tcl command, but it looks like it has been removed from the interpreter, presumably because it is being run in an environment which wants to keep on running. (Tcl definitely supports defining interpreters with restricted command sets.) You'll have to check the application documentation on what to use instead.
Poking around in what Google digs up, the qexit command (if defined) might work instead. It's apparently called like this:
qexit -error
I've no idea why they don't follow the standard exit protocol.
We implemented some tcl commands, if we type only part of the command at Tcl> prompt in tcl shell interactive mode, the tcl shell can recognize the command. But if we put the same partial command in tcl script file, then source the script from tcl shell, unknown command will be reported. And the whole command in tcl sript can be recognized.
How can we make source tcl script behavior same as shell interactive mode? We expect when source tcl script, partial command can also be reconginzed.
Please see following sample.
Partial command can be recognized in shell interactive mode.
Tcl> my_prove
Info: proving started
Info: ....
Info: ....
Tcl> my_pro
Info: proving started
Info: ....
Info: ....
Partial command cannot be recognized when source run.tcl script.
a) run.tcl
setup_design
my_prove
my_pro
b) source the script run.tcl
Tcl> source run.tcl
$inside source$$> setup_desgin
Design setup...
Done
$inside source$$> my_prove
Info: proving started
Info: ....
Info: ....
$inside source$$> ::unknown my_pro
invalid command name "my_pro"
Tcl implements partial command name expansion in the unknown procedure (along with numerous other things) and only turns it on in interactive mode. It's generally strongly recommended to use full command names in your scripts; that's far more likely to be reliable.
If you want to enable it, which I don't think you should, do this (this version uses tailcall so needs at least Tcl 8.6):
rename unknown _standard_unknown
proc unknown args {
set cmd [lindex $args 0]
set matches [uplevel 1 [list info commands $cmd*]]
# If there is a unique match, use it
if {[llength $matches] == 1} {
lset args 0 [lindex $matches 0]
tailcall {*}$args
}
tailcall _standard_unknown {*}$args
}
In theory, you can also set the tcl_interactive global to any true value (e.g., 1) to enable the expansion. However, there may be other unwanted behaviours as well enabled by doing that; Tcl makes no guarantees on that front.
I am using a .do file which is used by GUI and by .tcl in command line (vsim -c) for simulating in Modelsim 10.3c
exec vsim -c -do DoFile.do
What I need is:
If an error happens, modelsim should be quit and return to the .tcl. Otherwise it should simulate the project.
If I put the line onerror { quit -f } in my .do file the GUI is quit at the first error. So, this is not comfortable.
I didn't manage to use onerror (warning: onerror command for use within macro) or $error (unknown variable) inside tcl
I would need further information about your DO and Tcl script but you can use try-catch on vcom (for compiling VHDL) or vlog (for compiling Verilog/SystemVerilog).
Here a short a example how to use it:
# set variable for compile error
set comperror ""
# compile files
catch "vcom -quiet -93 -work work name.vhd" comperror
catch "vcom -quiet -93 -work work name2.vhd" comperror
# ... and futher files..
if [expr {${comperror}!=""}] then {
# quit modelsim or do anything else
} else {
# do simulation or execute further commands
}
You can compile ALL files and if a error occurs you can quit it. If it's successful you can run your simulation.
I have found a work around. I create a file in the .tcl and put the following lines into the .do scripts:
if [file exists ../Command_Line_Enable.txt] {
onerror { quit -f }
}
So, if that file is not generated the GUI will not exit.
I realized that as I run makefiles from my main makefile, if they child makefiles fail, the parent continues and does not return with an error exit code.
I've tried to add the exception handling...but it does not work. Any ideas?
MAKE_FILES := $(wildcard test_*.mak)
compile_tests:
#echo "Compiling tests.$(MAKE_FILES)."
#for m in $(MAKE_FILES); do\
$(MAKE) -f "$$m"; || $(error Failed to compile $$m)\
done
You cannot use make functions like $(error ...) in your recipe, because all make variables and functions are expanded first, before the shell is invoked. So the error function will happen immediately when make tries to run that recipe, before it even starts.
You have to use shell constructs to fail, not make constructs; something like:
compile_tests:
#echo "Compiling tests.$(MAKE_FILES)."
#for m in $(MAKE_FILES); do \
$(MAKE) -f "$$m" && continue; \
echo Failed to compile $$m; \
exit 1
done
However, even this is not really great, because if you use -k it will still stop immediately. Better is to take advantage of what make does well, which is run lots of things:
compile_tests: $(addprefix tests.$(MAKE_FILES))
$(addprefix tests.$(MAKE_FILES)): tests.%:
$(MAKE) -f "$*"
One note, if you enable -j these will all run in parallel. Not sure if that's OK with you or not.
I am trying to produce a memory (simple dual port ram) using core generator in xilinx 14.2. The problem is that during synthesis says :
ERROR:sim - Failed to run command ' -p xc3s100e-5cp132 -sd
"C:/Users/ORiON/register_file/ipcore_dir/tmp/_cg/_dbg/" -sd
"C:/Users/ORiON/register_file/ipcore_dir/tmp/_cg/" -dd
"C:/Users/ORiON/register_file/ipcore_dir/tmp/_cg/_dbg/" "MEM_aRd_sWr_16x32"
"C:/Users/ORiON/register_file/ipcore_dir/tmp/_cg/MEM_aRd_sWr_16x32.ngc"
-intstyle xflow'. Executable file not found.
ERROR:sim - Failed executing Tcl generator.
Wrote CGP file for project 'MEM_aRd_sWr_16x32'.
Core Generator create command failed.
ERROR:sim - Failed to generate 'MEM_aRd_sWr_16x32'. Failed executing Tcl
generator.
The command itself is missing.
Failed to run command 'A_COMMAND_SHOULD_BE_HERE -p xc3s100e-5cp132 -sd
I assume it's a kind of script or makefile who is calling this command and the command is defined as a variable. And the variable is not assigned. Something like that?