INW-SAM servername01 9999 3032 RUNNING Apr 27 17:22:07 2010
I'm trying to extract the 4th field, which is a PID, (3032) so I can
pass the PID to a kill process command. Below is the command I'm
using to trying to extract the data with:
for /f "tokens=4 delims=" %%G in (find.tmp) do @echo G: %%G
However, my logic (or lack of understanding of tokens) is wrong. Any
help is appreciated!
"tokens=4 delims= "
You need to set the delims to a space or tab as the case might be - or
remove the delims= entirely as the default is already space and tab.
--
Regards,
Mic
or
for /f "tokens=4" %%G in (find.tmp) do @echo G: %%G
work both. You must specify the blank char when you use delims keyword or
you must omit delims keyword because space char is delimter by default.
Regards
Thomas
Hi Hank,
well the tokens=4 is right but by disabling the delimiters all content
will fit in token 1 which you skipped.
Since space is a standard delimiter you simply can omit the delims=
specifier.
--
Regards
Matthias
for /f "tokens=4 delims= " %%G in (find.tmp) SET PID=%%G
TASKKILL /PID %PID%
Thanks for any help!
Hank
You left the DO keyword out of the for in do command - is that a copy and
paste?
--
Regards,
Mic
Hi Hank,
if you use an nonexistent Pid you get a different error message,
Looks like PID is not defined, you could check it prior to using it,
But better you'd don't use a canned PID from a file but get the actual
PID with tasklist or whatever you used to generate find.tmp.
--
Regards
Matthias
C:\restart_sm_service
1968 set PID=1968
ERROR: Invalid syntax. Value expected for '/pid'.
Type "TASKKILL /?" for usage.
Did you follow Mic's tip and insert the missing do?
What is that number 1968 in front of the set?
Please post the batch part which generates the temp file also,
Maybe we can construe a parsing for /f which gets the pid directly.
--
Regards
Matthias
@echo off
d:
cd d:\incharge7\sam\smarts\bin
brcontrol>c:\temp\brcontrol.tmp
c:
cd \temp
findstr /c:"INW-SAM ENPEFRSMA01.afspdev 9999 "
brcontrol.tmp>find.tmp
for /f "tokens=4 delims= " %%G in (find.tmp) do @echo %%G set PID=%%G
do @echo %%G
taskkill /pid %PID%
> Here's the complete batch file.
> Note that I'm pulling the PID from a third-party application
> (hence brcontrol).
That doesn't matter. As long as that app outputs to stdout it can be
parsed with a for /f.
Try this modified batch without temp files.
@echo off
set Search="INW-SAM ENPEFRSMA01.afspdev 9999 "
Pushd "d:\incharge7\sam\smarts\bin"
for /f "tokens=4" %%G in (
'brcontrol ^|findstr /I /C:%Search%'
) do set PID=%%G
echo PID=%PID%
if Not defined PID Echo PID not defined & Pause & goto :Eof
taskkill /pid %PID%
POPD
HTH
--
Regards
Matthias
The syntax of the FOR command is
For ..options.. %%v in (list) do statement
Not sure whether this is physically on one line or two:
for /f "tokens=4 delims= " %%G in (find.tmp) do @echo %%G set PID=%%G
do @echo %%G
But it should be (as one line)
for /f "tokens=4 delims= " %%G in (find.tmp) do echo %%G&set PID=%%G&echo
%%G
* The "@" is NOT required. it merely suppresses echoing of the ECHO command
itself to screen. Normally, the first line of batch is
@echo off
which turns OFF the echoing off commands to screen - the "@" here suppresses
the echoing of this initial ECHO command
To form a compound statement, separate each individual statement by "&" on a
physical line
OR
for /f "tokens=4 delims= " %%G in (find.tmp) do (
echo %%G
set PID=%%G
echo %%G
)
Where each individual statement is on its own separate line and the set of
lines is parenthesised. The opening parenthesis must be on the same physical
line as the DO.
* You can combine statements using the "&" separator if you prefer
* The first statement may follow the opening parenthesis on the same
physical line
* The closing parenthesis may terminate the final physical line; it does not
have to be on its own line
If you have the second "do @echo %%G" on a separate physical line as it
appears from your post, then %%G is out-of-context at that point. It only
remains in-context for the "for" line (and any parenthesised statement-set
following.)
In your case, the system should have shown
1968 set PID=1968
%G
or
1968 set PID=1968 do @echo 1968
depending on where your line-break (if any) occurred. Either way, the
variable "PID" would not have been set.
@echo off
set Search="INW-SAM ENPEFRSMA01.afspdev 9999 "
Pushd "d:\incharge7\sam\smarts\bin"
for /f "tokens=4" %%G in (
'brcontrol ^|findstr /I /C:%Search%'
) do set PID=%%G
echo OLD-PID=%PID%
rem sm_service stop ic-sam-server
echo OLD-PID=%PID%
for /f "tokens=4" %%G in (
'tasklist /NH /fi "PID eq %PID%"'
) do set PID=%%G
if "%pid%"=="" echo No PID found & exit /b
echo NEW-PID=%PID%
> > Matthias- Hide quoted text -
>
> - Show quoted text -
>Okay, another question. I only get to work on this maybe one hour a
>week if I'm lucky, hence the sporadic questions! Anyway, I (tried) to
>modify the code to look for the absence of the PID after I stop it,
>but the do set command is setting it to 0. I'm missing something
>obviously. Here's the code:
>
>@echo off
>set Search="INW-SAM ENPEFRSMA01.afspdev 9999 "
>Pushd "d:\incharge7\sam\smarts\bin"
>for /f "tokens=4" %%G in (
> 'brcontrol ^|findstr /I /C:%Search%'
> ) do set PID=%%G
>echo OLD-PID=%PID%
>
>rem sm_service stop ic-sam-server
>
>echo OLD-PID=%PID%
>
>for /f "tokens=4" %%G in (
> 'tasklist /NH /fi "PID eq %PID%"'
> ) do set PID=%%G
> if "%pid%"=="" echo No PID found & exit /b
>echo NEW-PID=%PID%
Try this modification:
for /f "tokens=2" %%G in (
'tasklist /NH /fi "PID eq %PID%"'
) do set PID=%%G
You were setting it to the Session# and not the PID column - but why you
are sitting the PID again, once you already have the PID?
--
Regards,
Mic
1. Capture the PID of a process that I need to restart.
2. Stop the process (using sm_service stop)
3. I have to now wait for the process to complete writing out its temp
files, so I'm checking to see when the process is NULL.
4. Once it's NULL, then restart the process again.
Hank
On May 18, 7:08 am, foxidrive <got...@woohoo.invalid> wrote:
> You were setting it to the Session# and not the PID column - but why you
> are sitting the PID again, once you already have the PID?
>
> --
> Regards,
> Mic- Hide quoted text -
>Here's the gist of what I'm trying to do:
>
>1. Capture the PID of a process that I need to restart.
>2. Stop the process (using sm_service stop)
>3. I have to now wait for the process to complete writing out its temp
>files, so I'm checking to see when the process is NULL.
>4. Once it's NULL, then restart the process again.
If it's a service that you are stopping:
@echo off
net stop ic-sam-server
:loop
net start |find /i "ic-sam-server">nul && goto :loop
net start ic-sam-server
--
Regards,
Mic
If only it was that simple! :-) The application (SMARTS-in-Charge)
creates numerous processes called sm_server (with unique PIDs), but
each one performs a different function, hence the reason I can't just
kill the sm_server process. I have to use the sm_service stop ic-sam-
server command to stop the specific process.
On May 18, 11:43 am, foxidrive <got...@woohoo.invalid> wrote:
> On Tue, 18 May 2010 09:28:34 -0700 (PDT), Hank
>
>On May 18, 11:43�am, foxidrive <got...@woohoo.invalid> wrote:
>> On Tue, 18 May 2010 09:28:34 -0700 (PDT), Hank
>>
>> <hammerin.hanks...@gmail.com> wrote:
>> >Here's the gist of what I'm trying to do:
>>
>> >1. Capture the PID of a process that I need to restart.
>> >2. Stop the process (using sm_service stop)
>> >3. I have to now wait for the process to complete writing out its temp
>> >files, so I'm checking to see when the process is NULL.
>> >4. Once it's NULL, then restart the process again.
>>
>> If it's a service that you are stopping:
>
>If only it was that simple! :-) The application (SMARTS-in-Charge)
>creates numerous processes called sm_server (with unique PIDs), but
>each one performs a different function, hence the reason I can't just
>kill the sm_server process. I have to use the sm_service stop ic-sam-
>server command to stop the specific process.
>
This is based on your code but the tasklist command looks for a string that
is returned to STDERR when the PID is not found.
@echo off
set Search="INW-SAM ENPEFRSMA01.afspdev 9999 "
Pushd "d:\incharge7\sam\smarts\bin"
for /f "tokens=4" %%G in (
'brcontrol ^|findstr /I /C:%Search%'
) do set PID=%%G
echo OLD-PID=%PID%
rem sm_service stop ic-sam-server
:loop
tasklist /FI "PID eq %pid%" 2>&1 |find /i "INFO: No tasks">nul || (
goto :loop
)
--
Regards,
Mic
So why don't you reuse the snippet known to be working?
I stuffed it into a sub (untested)
I integrated a timeout when waiting for the service to stop.
the ping waits 2 seconds berfore retrying and the count is 30 making
one minute, change these numbers to your liking.
:: ------------------------------------------------------------------
@Echo off&Setlocal
set Search="INW-SAM ENPEFRSMA01.afspdev 9999 "
Call :GetPid PID
If Not defined PID Echo Service not running & goto :Eof
:: stop Service
sm_service stop ic-sam-server
Set Cnt=0
:Redo
If %Cnt% GTR 30 Echo Timeout stopping service&Pause&Goto :Eof
Call :GetPid PID
if defined PID Ping -n 2 Localhost >NUL &Set /A Cnt+=1 &Goto :Redo
Echo Service(ses) are down
:: do whatever
Goto :Eof
:GetPID PID ---------------------------------------------------------
setlocal
if defined PID set "PID="
Pushd "d:\incharge7\sam\smarts\bin"
for /f "tokens=4" %%G in (
'brcontrol ^|findstr /I /C:%Search%'
) do set PID=%%G
popd
Endlocal&Set "PID=%PID%"
:: ------------------------------------------------------------------
HTH
--
Regards
Matthias
2>&1 |find /i "INFO: No tasks">nul || (
goto :loop
)
>Thanks Mic. Can you explain this piece of code you're using:
>
>2>&1 |find /i "INFO: No tasks">nul || (
>goto :loop
>)
">2&1" sends the STDERR stream to the same place that STDOUT is going.
In the above they will both be piped to FIND.
"||" and "&&" evaluate the errorlevel of the previous command and execute
the following commands. || executes on errorlevel 1 or higher and &&
executes on errorlevel 0.
In the above if the string is not found it will branch to the :loop label.
Or it should - I didn't test it.
--
Regards,
Mic