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!

Spawning a MS DOS PROMPT 1

Status
Not open for further replies.

komyg

Programmer
Dec 13, 2005
68
BR
Ok, I just need to spawn console based program and input commands to it.
So I started with something simple, opening a ms dos prompt and sending commands to it, but as I try to do this using:
"spawn -console cmd.exe", the process is created but the prompt window doesn't pops up.
What am I doing wrong?

Please Help,
Komyg
 
What if you get rid of the -console flag ??
 
I've tried that, but it doesn't work.
 
Although I've never worked with Expect in the PC world, I have some time to help ...

Can you provide your Expect code?
 
The problem is I have no source code yet. I'm just playing with the tcl console.
The commands i've been using are:

set tty_spawn_id "c:/windows/system32/"
set stty_init raw
spawn -console cmd.exe # Or spawn cmd.exe
exec cmd
# This last command starts the cmd in the same console I'm # typing, but the prompt only works properly in the
# Tclsh84 console. In the Wish84 and Tkcon the console tcl # displays:
# Microsoft Windows XP [Version 5.1.2600]
# (C) Copyright 1985-2001 Microsoft Corp.
#
# C:\Tcl\bin>
# and then it exits the console.

So I just need that the console opens in a new window and that I can control it's stdin. I believe that if I can do
exec ?? | cmd, I can make the stdout of the tcl console (I don't know how to specify this to the tcl console, hense the ??) be piped to the stdin of the cmd.

Thanks,
Komyg
 
Lets try this simple test 1st ...

1st, kick-off your interactive tcl session so that your at the "%" prompt.

enter the following ...
(Note: the ###'s are my comments)

> package require Expect ### should come back with a ver num
> spawn /thefullcorrectpath/cmd.exe ### whatever you want to run
> interact ### this should put you the cmd.exe mode

Then from here type want you would normally type/do if you executed the cmd.exe program in the typical fashion (i.e. - not via tcl/expect).

To exit out of this interact session and back to the "%" prompt", type exit/close/ctrl-c, etc. as you would normally do in the cmd.exe program.

What this (should of) have done was open an interactive session of your spawned process.

If this works for you, then I can explain farther as to how you can send commands to the spawned process and interact on the return values from the spawned process.

[I've successfully tested this in a unix environment, but not in the pc world]

Let me know how you make out ...
 
I'm sorry I took so long to answer, but it was New Year's eve, and I didin't work then.
I tried to use the command interact, but it is not implemented on Windows, so if I type:

>package require Expect
>spawn cmd.exe
>exp_interact

nothing happens. And if I type that into the wish84 console, it says that command doesn't exist (the same happens in the tclsh84 if I type the command as "interact" instead of "exp_interact"). I've tried some variations of the interact command, like

>exp_interact {
>a
>{send_user "you typed a\n"; send "a";}}

but as I suspected, that didin't work either.
There must be another command that does this, but I don't know what is it.

Thank you very much,
Komyg
 
Hmmm, didn't realize interact hasn't been built into Expect for windows yet (see ...

anyway, try this ...

1>package require Expect
2>spawn cmd.exe
3>expect "see full description below"
4>send "your cmd.exe command\r"
... and you could go on and on with a "conversation" with the spawned process.

Note: It's always good to wait for prompts before sending information to the process. (line 3)

Full description: put in line 3 whatever the return prompt would be as if you ran the cmd.exe program (e.g. - c:\windows). It doesn't need to be the complete return prompt, just some portion (yes regexp's can be used too).

And oh, BTW, when you spawn a process, it's now explicitly opening a new console window (I think you eluded to this earlier.)
 
Hurray!!!
That works very well, thank you!
Now, how can I get the process ID of a process that's already running (I cannot start the process)?

Thank you,
Komyg
 
I forgot to tell you that I am tring to spawn the cmd on another computer that has the Windows Server 2003 Standard Edition, but as soon as I spawn the cmd process, it magicaly stops running.
What can I do?

Thanks,
Komyg
 
You could "spawn" another process (i.e. - nest them) and go through a normal conversation using the two combo-cmds "expect" & "send".

Note that even though each spawn process creates an unique 'identifier' (i.e. - $spawn_id variable), by default the 'send' and 'expect' cmds communicate with the most recently spawned process. Yes there are ways to talk to each process by using the -i suffix on the 'expect' & 'send' cmds - but this does require you to set the $spawn_id variable after each spawned process.
e.g.

> spawn cmd.exe
> set cmd_id $spawn_id
> send -i $cmd_id "whatever\r"
> expect -i $cmd_id "whatever"
...

Let me know how you make out!
 
And to answer your question " how can I get the process ID of a process that's already running" ...

It's simple in unix, but you tell me what (DOS) cmd will give you a listing of running processes? Once you know that, just search for the name of the process (like unix's grep) and pull off the procid.

 
Ok, I have the process ID. Now how do I input commands to it?

Thanks,
Komyg
 
I'm not sure how you are going to do this, but 1st let me understand what you got so far...

You have a process id from an existing process (i.e. - Windows Server 2003 Standard Edition, you mentioned).

What do you want to do with program?
How would you "work" with this program if say you were able to execute/start this process?

P.S. - I'm testing something now in anticipation of your answer (I'm trying dude, don't want to leave you hanging)
...Let me know.
 
Ok, the problem is that when I create the cmd process, it is shutdown imediately after.

So I'm trying to bypass that by opening a cmd manualy and getting the process id. With that I should be able to input commads to it, i.e. send "exec ODA 4659 1\r\n" (exec ODA 4659 1 is the command I must send), but I don't know how to send this command.

I've tried setting the variable spawn_id to the value of the cmd process id, but when I input the command I get an error saying that the channel (that has the value of spawn_id) doesn't exist.

So far, I've been trying to create this channel, but I don't know how to do it.

I think that because I didin't spawn the cmd process, there are no pipes leading from my program to it. I didin't saw any commands to create this pipes though.

PS: The cmd output was only important in the first phase so that I could be sure that I was really controlling the cmd. Now it's not important.

Thank you very much dude you've been a great help to me here.
Komyg
 
Let's see your code (pic worth 1000 words)...

and just so I understand,your trying to ...

once you know the procid of the Windows Server 2003 process, you want to send the command:
exec ODA 4659 1\r\n , where 4659 is the procid, right?

(What making this hard for me is that I can't test any of this PC interaction stuff, so I'm relying on you to provide as much detail as possible.)
 
Ok, for now my source code is:

package require Expect
cd c:/nm
spawn cmd.exe
send "wmconsole RC1\r\n"
send "exec ODA 4659 1\r\n"
expect "RC1"
cd c:/felipe
puts "end"

It's just a test source code, and it doesn't work properly because cmd process is closed just after it's started.
An updated version of this code, that considers the problem above would be:

# NOTE: The user would have to manualy open a cmd and type # in it wmconsole RC1

package require Expect
set id [pv wmconsole.exe] # this will get the process id
set spawn_id $id

# At this point a channel leading from my program to the
# wmconsole process should be created in order to enable
# the send command to work, otherwise it returns an error
# message "cannot find channel $spawn_id", where $spawn_id # is the value of the variable spawn_id.

send "exec ODA 4659 1\r\n
 
Using your last code snipet...
1st, you've got some basics wrong.

In...
set id [pv wmconsole.exe]
set spawn_id $id


This is incorrect. The spawn_id is an Expect system variable that is automatically set each time a process is spawned. Thus to retain this id value to use later, you need to set your own variable to this value.
> set cmd1_id $spawn_id

Also, once you spawn a process you should include an "expect" cmd to explicitly wait for whatever is returned as a result of the spawned process. Usually it's sufficient to use the typical prompt (or some subset string of).
e.g. > expect "c:\blah>"

Then you can "send" anything you want to spawned process as if your where typing this directly from this prompt.
e.g. > send "dir\r"

AFTER each "send" cmd, you should again have some kind of "expect" cmd so that your 'next' cmd doesn't prematurely execute before the "send" cmd is executed (it's good practice - you could get undesirable results).

This sequence of cmds is what I referred to as the two combo-cmds: "expect" & "send".

Now, if you need to spawn another process while you’re in a spawned process, you can. Remember, that even though each spawn process creates a unique 'identifier' (i.e. - $spawn_id variable), by default the "send" and "expect" cmds communicate with the most recently spawned process.

However, in you case you really don't need to even retain the $spawnd_id of each process because you're really just nesting each spawn process and thus each subsequent "expect" and "send" cmd will be applied to most recent spawned process. Once you closeout the most recent spawned process (via a "send" cmd, e.g. - send "exit\r" – Note: you should use a subsequent “expect” cmd after the “send”), you'll be back at the previous process spawned. Saving the $spawn_id value is useful and used when you want to communicate to each ‘interactive’ spawned process regardless of when you initially spawned the process (using the -i, flag, e.g. send -i $cmd1_id "blah\r").

I suggest you 1st test multiple spawned processes and subseqeuntly talking to each one (i.e. - using the "expect" & "send" cmds) using a simple interactive program like cmd.exe. Spawn a cmd.exe program, run some simple commands on this process, then from this process spawn a 2nd cmd.exe process and run some more commands. Basically your program should mimic what you could do if you did this manually.

Hope this helps ...
 
Ok, I was changing the value of spawn_id because my program didin't spawn the cmd, this was done manualy trough: "start -> execute -> cmd.exe", so I was changing the spawn_id in the hope that "send" would send a command to this cmd, but it didin't work out.

On the other hand, I used send -i $id "command\r\n", and the Wish didin't complain, but the prompt didin't receive the command either. So the last thing I'm missing for this to work is a channel between the cmd and my program.

How do I create this channel?

Thanks,
Komyg
 
If I understand you, I think you need something like:

> expect -i $id "somereturnprompt"

Again, let's see your latest code ...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top