Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

how to execute "source" command in tk?

Status
Not open for further replies.

rotomac

Technical User
Sep 24, 2003
13
US
hi,

i want to source file using tk.
source /home/user/abc.csh

how can i do it using tk?

roto
 
Your syntax is right but the "source" command in Tcl (or Tk) is only useful for accessing Tcl/Tk scripts. From your statement, I gather that the file you want to execute is a c-shell script? If that's so, you will have to use "exec".

Bob Rashkin
rrashkin@csc.com
 
hi bob,

yes,i even used exec /user/home/abc.csh it is saying
ERROR:couldnt execute "/user/hime/abc.csh" no such file or directory.

The file is there in correct location.
What might be the problem.

Thanks
Bob
 
I can't see why. I don't work much with UNIX and I don't know how much behavior carries over from Windows. It ought to be like "exec"ing a .bat file which I do all the time. Try "cd" to /user/home and then "exec abc.csh".

Bob Rashkin
rrashkin@csc.com
 
Did you set the execute flag?
Code:
  chmod +x /user/hime/abc.csh
HTH

ulis
 
hi ulis,

i can execute thru command line.i just want to execute thru tcl/tk.
how can i execute the follwoing unix command thru tk?
source /user/home/abc.csh

Thanks
Roto
 
As Bong said you,
Code:
source
is only for Tcl scripts.

From your previous message I can see a typo (maybe in the reporting of the error, maybe in the code you used):
ERROR:couldnt execute "/user/hime/abc.csh" no such file or directory.

Without more info on what you did, I can only try to guess what went wrong. If you didn't included csh magic inside your csh script, you need to do:
Code:
  exec csh /user/home/abc.csh

ulis
 
hi ulis,

yes,now it is ok. But it is not doing what i expected.
this what i am doing in unix commmand:
source /home/user/abc.csh

if i try to do the same in tcl, i used
exec csh /home/user/abc.csh
tcl is not giving and errors but it is not working what it worked in unix.

can you suggest me some other solution??
 
Can you say us what is expected and what you (don't) obtain?

Maybe you only need the redirection of the output to be happy (or a cd before the exec).

ulis
 
hi ulis,

I have some path seting inside the .csh file.
When i source /user/home/abc.csh in unix command line
then i can use galdiator & (This is excutable)

When i do the same using tcl like
exec csh /user/home/abc.csh
it is running fine without any problem.
But when i used galdiator & it is saying command not found why???
 
You don't said enough about what you do with tcl but I'll try to guess again.

Correct me if this is not true:
1/- you enter a terminal session
- you have a generated csh script that let you cd to the right directory where to launch gladiator
- after that you enter the command:
Code:
source /user/home/abc.csh
you can enter the command:
Code:
gladiator &
and all works fine
2/- you enter a tclsh session
- you have a generated csh script that let you cd to the right directory where to launch gladiator
- after that you enter the command:
Code:
exec csh /user/home/abc.csh
you can enter the command:
Code:
exec gladiator &
but you get the message
Code:
file not found

If this is correct, I can say you why.
I don't know csh but can guess that the
Code:
source
command of csh is roughly the equivalent of
Code:
.
(dot) command in sh. That's the called script is evaled in the context of the caller script (more below).

1/ The
Code:
source
command of csh and the
Code:
source
command of Tcl do similar things but not the same.
2/ source in csh modify the file environment at the session level (roughly: does a cd for you).
exec in Tcl launches a csh session that is different of your tclsh session and when the csh returns, UNIX restores the cd of tclsh (it's not what you wanted). And it's why you get the message (the cd that you need is vanished).

An explanation about programs environment:
In UNIX all programs have an environment where are defined variables as PATH.
When a program calls a program (when tclsh launches csh) the environment of the caller is copied in the environment of the called. So all modifications of the environment of the called do NOT modify the environment of the caller.
Only shell scripts can do a magic: with the dot command or the source command they can modify their environment from the script called (because it's them that interpret the called script). And tclsh can do the same magic with it's source command.

What you can do?
1/ Use only csh and cd thru the source command of csh.
2/ Use only tclsh and cd thru the source command of tclsh.
For the later, the generated script must be a Tcl script:
Code:
  cd .../gladiator
(.../gladiator has to be replaced by the right directory where gladiator lies).

HTH

ulis
 
Just my 2 cents on the subject, but I've had to work this out in the WinX env, so maybe it will be helpful.

One of the issues had to do with an error mentioned elsewhere, basically indicating that it could not locate the file or dir when doing "exec someprog.cmd" (note it works OK with .bat). The key in the above content on this incident was to specify the shell in which to exec the script, so:

exec cmd /c myprg.cmd

seems to work OK.

Below is a proc that I use to exec, and then do some DOS level error checking. Some of the procs called are not included, but you can figure out basically what is going on.

Note some of the PROCs not included:

-xGenPassword (originally created to autogenerate random passwords for the Matrix PDM system, the auto email the user his acct info, but I use it here to get a random script name)
-xBuildFilePath (parses out the filename from the path elements. If no dir or filename passed, it will automatically create an existant filepath with a random generated filename)
-xWriteTxtFile (will take the content arg and write the text file, with all needed error checking, path creation, etc. if no file name/path info, creates default random generated file in %TEMP%\random.txt. In this context xProcessWrapperName is used as a PID also)
-xReadTxtFile (this opens the text file and reads the content into a TCL var. Here, xProcessWrapperSemaphore is a text file generated by the above DOS CMD script, and then is opened to get the DOS errorlevel status of the process. Also checked is the EXEC status. If EXEC returnval does not catch some program failure, hopefully this will)
-notify/warning/err (standard user I/O routines. Note err also gives thread information in the error message so that the program executed and the PROC in which the error is generated is displayed - good for debugging, drives users nuts).



Best regards, John Lopez

#----------------code frag--------------------#
proc xForkOSProgram {xProgram args} {

global TRUE FALSE ERROR WARNING NOTIFY

#exec myprog.cmd
#0: Successful with no errors or warnings
#1: Warnings
#2: Errors
#3: Fatal Errors

#~create the CMD script to wrap the xProgram to be run
set xProgramBasename [file rootname [file tail $xProgram]]
set xProcessWrapperName [xGenPassword $xProgramBasename]
set xProcessWrapperSemaphore [xBuildFilePath $xProcessWrapperName "sem"]
set xProcessWrapperContent [subst -nocommands {

@echo off
start "Matrix Forked Process: $xProgramBasename" /B /MIN /WAIT cmd /c $xProgram $args
IF ERRORLEVEL 0 echo EXECSTATUS=SUCCESS > $xProcessWrapperSemaphore
IF ERRORLEVEL 1 echo EXECSTATUS=WARNING > $xProcessWrapperSemaphore
IF ERRORLEVEL 2 echo EXECSTATUS=ERROR > $xProcessWrapperSemaphore
IF ERRORLEVEL 3 echo EXECSTATUS=FATAL > $xProcessWrapperSemaphore
IF ERRORLEVEL 4 echo EXECSTATUS=UNKNOWN > $xProcessWrapperSemaphore
EXIT /B

}]

set xProcessWrapper [xWriteTxtFile $xProcessWrapperContent $xProcessWrapperName "CMD"]

if {[file exists $xProcessWrapper] == $TRUE} {

set errcode [catch {exec -keepnewline -- cmd [file nativename $xProcessWrapper]} errmsg]
if {$errcode != $FALSE} {
err "exec $xProcessWrapper fork process failed" "$errcode" "$errmsg"
}

if {[file exists $xProcessWrapperSemaphore] == $TRUE} {
set xSemaStatus [string trim [lindex [split [xReadTxtFile $xProcessWrapperSemaphore] =] 1]]
set xSemaMsg "eMatrix forked process $xProgram : $xSemaStatus"
switch -- $xSemaStatus {
SUCCESS { set errcode $NOTIFY
notify "$xSemaMsg"
}
WARNING { set errcode $WARNING
warning "$xSemaMsg"
}
ERROR { set errcode $ERROR
err "$xSemaMsg"
}
FATAL { set errcode $FATAL
err "$xSemaMsg"
}
UNKNOWN { set errcode $UNKNOWN
err "$xSemaMsg"
}
default { set errcode $WARNING
warning "$xSemaMsg"
}
}; #~endSwitch

} else {
set errcode [err "failed to resolve Forked Process Semaphore: $xProcessWrapperSemaphore"]
}

} else {
set errcode [err "could not locate to fork $xProgram, exec failed"]
}

return $errcode

}; #~endProc


John Lopez
Enterprise PDM Architect
lopez.john@goodrich.com
 
I am using unix os and tcl/tk.I will tell my requirement below:
I have three .csh files and each file contains differant path setting and environment settings.I want
to use tk and source the .csh file.For an example,in
unix terminal if i type "source one.csh" it is setting
the correct path and environment settings. similarly for the other two .csh file.
I want to source these .csh files through tcl/tk.I have a list box in tk which contains one,two,three.if i click one it should execute "source one.csh" file.if i click two it should execute "source two.csh".

Is there any way to do this?

Roto
 
Again, I think where you are at is that the .CSH scripts must be executed within a CSH shell that can interpret them. TCL is not going to interpret CSH commands in your scripts. So sourcing the CSH scripts into the TCL source will not get it.

Using exec() will give you the desired results I belive. However, when you exec, remember that exec does not know what shell to execute the script in. In effect the command you are exec'ing is NOT one.csh, it is csh, with the argument one.csh. CSH then in turn interprets the content of one.csh.

One of the issues between processes that are not tightly bound together, such as programs invoked by exec, is that of inter-process communications. The above concept can be applied to your situation also.

I think the way I'd do it is to:

exec csh one.csh $PID

where PID is a process ID handle that is passed to the shell program.

Then when the shell program executes, it writes to a file in the OS, ie: /tmp/$PID.log the status of execution and any error messages generated by one.csh.

Then, when the thread completes, and returns control to TCL, have the TCL script look for a file in the OS called /tmp/$PID.log, open it an analyze it's content. Obviously you need some structured messaging. Above, my "semaphore" (not really) contains a status string that my TCL program extracts and makes a judgement on how the external process faired in execution.

Note the "ProcessWrapper", is a inline script built and executed by the TCL program, that in turn executes the desired program, in my case a Winx EXE, so I am constrained to attempt to get the DOS level errorlevel information, which is redirected into a text file for later retreival.

Hope this helps.

John Lopez
Enterprise PDM Architect
lopez.john@goodrich.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top