Check the machine is accessible or not using command - command-line

I have batch file in which i am restarting a machine and want to check if machine is back online then execute the code block else after particular time inform the user the machine is not online
I want to check something like:
pingresult = ping \\machinename
if (pingresult == true)
{
execute some task
}
else
{
keep pinging for say 5min. if after 5mins machine is not up show message to user
}

This will try pinging %machinename% for 100 times with a default timeout of 3 seconds: 3s * 100 = 300s, i.e. 5 minutes.
for /L %%N IN (1, 1, 100) DO (
ping -n 1 %machinename%
if not ERRORLEVEL 1 (
set pingresult=true
goto done
)
)
set pingresult=false
:done
if %pingresult% == true (
echo "ping ok, doing something..."
) else (
echo "no reply after 5 mins, error!"
)

Related

How to break a MATLAB system call after a specified number of seconds

I am using Windows MATLAB to run SSH commands, but every once in a while the SSH command hangs indefinitely, and then so does my MATLAB script (sometimes when running overnight). How can I have a command time-out after a certain amount of waiting time? For example, suppose I don't want to wait more than 3 seconds for a SSH command to finish execution before breaking it and moving on:
% placeholder for a command that sometimes hangs
[status,result] = system('ssh some-user#0.1.2.3 sleep 10')
% placeholder for something I still want to run if the above command hangs
[status,result] = system('ssh some-user#0.1.2.3 ls')
I'd like to make a function sys_with_timeout that can be used like this:
timeoutDuration = 3;
[status,result] = sys_with_timeout('ssh some-user#0.1.2.3 sleep 10', timeoutDuration)
[status,result] = sys_with_timeout('ssh some-user#0.1.2.3 ls', timeoutDuration)
I've tried the timeout function from FEX but it doesn't seem to work for a system/SSH command.
I don't think the system command is very flexible, and I don't see a way to do what you want using it.
But we can use the Java functionality built into MATLAB for this, according to this answer by André Caron.
This is how you'd wait for the process to finish with a timeout:
runtime = java.lang.Runtime.getRuntime();
process = runtime.exec('sleep 20');
process.waitFor(10, java.util.concurrent.TimeUnit.SECONDS);
if process.isAlive()
disp("Done waiting for this...")
process.destroyForcibly();
end
process.exitValue()
In the example, we run the sleep 20 shell command, then waitFor() waits until the program finishes, but for a maximum of 10 seconds. We poll to see if the process is still running, and kill it if it is. exitValue() returns the status, if you need it.
Running sleep 5 I see:
ans =
0
Running sleep 20 I see:
Done waiting for this...
ans =
137
Building on #Cris Luengo's answer, here is the sys_with_timeout() function. I didn't use the process.waitFor() function because I'd rather wait in a while loop and display output as it comes in. The while loop breaks once the command finishes or it times out, whichever comes first.
function [status,cmdout] = sys_with_timeout(command,timeoutSeconds,streamOutput,errorOnTimeout)
arguments
command char
timeoutSeconds {mustBeNonnegative} = Inf
streamOutput logical = true % display output as it comes in
errorOnTimeout logical = false % if false, display warning only
end
% launch command as java process (does not wait for output)
process = java.lang.Runtime.getRuntime().exec(command);
% start the timeout timer!
timeoutTimer = tic();
% Output reader (from https://www.mathworks.com/matlabcentral/answers/257278)
outputReader = java.io.BufferedReader(java.io.InputStreamReader(process.getInputStream()));
errorReader = java.io.BufferedReader(java.io.InputStreamReader(process.getErrorStream()));
% initialize output char array
cmdout = '';
while true
% If any lines are ready to read, append them to output
% and display them if streamOutput is true
if outputReader.ready() || errorReader.ready()
if outputReader.ready()
nextLine = char(outputReader.readLine());
elseif errorReader.ready()
nextLine = char(errorReader.readLine());
end
cmdout = [cmdout,nextLine,newline()];
if streamOutput == true
disp(nextLine);
end
continue
else
% if there are no lines ready in the reader, and the
% process is no longer running, then we are done
if ~process.isAlive()
break
end
% Check for timeout. If timeout is reached, destroy
% the process and break
if toc(timeoutTimer) > timeoutSeconds
timeoutMessage = ['sys_with_timeout(''',command, ''',', num2str(timeoutSeconds), ')',...
' failed after timeout of ',num2str(toc(timeoutTimer)),' seconds'];
if errorOnTimeout == true
error(timeoutMessage)
else
warning(timeoutMessage)
end
process.destroyForcibly();
break
end
end
end
if ~isempty(cmdout)
cmdout(end) = []; % remove trailing newline of command output
end
status = process.exitValue(); % return
end
Replacing ssh some-user#0.1.2.3 with wsl (requires WSL of course) for simplicity, here is an example of a function that times out:
>> [status,cmdout] = sys_with_timeout('wsl echo start! && sleep 2 && echo finished!',1)
start!
Warning: sys_with_timeout('wsl echo start! && sleep 2 && echo finished!',1) failed after timeout of 1.0002 seconds
> In sys_with_timeout (line 41)
status =
1
cmdout =
'start!'
and here is an example of a function that doesn't time out:
>> [status,cmdout] = sys_with_timeout('wsl echo start! && sleep 2 && echo finished!',3)
start!
finished!
status =
0
cmdout =
'start!
finished!'

YAML, cmd based shell, if else conditions is not working

I am writing CICD in the YAML file of GitHub, therein one instance I need to compare the branch names where a pull request is being triggered to determine which environment the other underlying process thereafter should use to the do MsBuild and other tasks.
Below is the comparison in YAML:
- name: build
shell: cmd
run: |
if not x%GITHUB_REF_NAME:RSDEV_=%==x%GITHUB_REF_NAME% (
SET PLATFORM=Qa
) else if not x%GITHUB_REF_NAME:Feature_=%==x%GITHUB_REF_NAME% (
SET PLATFORM=Qa
) else if not x%GITHUB_REF_NAME:Release_=%==x%GITHUB_REF_NAME%(
SET PLATFORM=Uat
) else (
echo "Check something went wrong"
exit 1
)
However, when I ran pull-request, it says
The syntax of the command is incorrect
Am I following the correct way for branch comparison like release_** and so on cmd?
Btw, I was able to figure out the reason behind the error: The syntax of the command is incorrect
There was an indentation error in the else block:
- name: build
shell: cmd
run: |
if not x%GITHUB_REF_NAME:RSDEV_=%==x%GITHUB_REF_NAME% (
SET PLATFORM=Qa
) else if not x%GITHUB_REF_NAME:Feature_=%==x%GITHUB_REF_NAME% (
SET PLATFORM=Qa
) else if not x%GITHUB_REF_NAME:Release_=%==x%GITHUB_REF_NAME%(
SET PLATFORM=Uat
) else (
echo "Check something went wrong"
exit 1
)
[Courtesy Edit]
The correct syntax in cmd.exe:
if /i not "%GITHUB_REF_NAME:RSDEV_=%" == "%GITHUB_REF_NAME%" (
SET "PLATFORM=Qa"
) else if /i not "%GITHUB_REF_NAME:Feature_=%" == "%GITHUB_REF_NAME%" (
SET "PLATFORM=Qa"
) else if /i not "%GITHUB_REF_NAME:Release_=%" == "%GITHUB_REF_NAME%" (
SET "PLATFORM=Uat"
) else (
echo Check something went wrong
exit 1
)

Save job output from SDSF into a PDS and using ISPF functions in REXX

We periodically runs jobs and we need to save the output into a PDS and then parse the output to extract parts of it to save into another member. It needs to be done by issuing a REXX command using the percent sign and the REXX member name as an SDSF command line. I've attempted to code a REXX to do this, but it is getting an error when trying to invoke an ISPF service, saying the ISPF environment has not been established. But, this is SDSF running under ISPF.
My code has this in it (copied from several sources and modified):
parse arg PSDSFPARMS "(" PUSERPARMS
parse var PSDSFPARMS PCURRPNL PPRIMPNL PROWTOKEN PPRIMCMD .
PRIMCMD=x2c(PPRIMCMD)
RC = isfquery()
if RC <> 0 then
do
Say "** SDSF environment does not exist, exec ending."
exit 20
end
RC = isfcalls("ON")
Address SDSF "ISFGET" PPRIMPNL "TOKEN('"PROWTOKEN"')" ,
" (" VERBOSE ")"
LRC = RC
if LRC > 0 then
call msgrtn "ISFGET"
if LRC <> 0 then
Exit 20
JOBNAME = value(JNAME.1)
JOBNBR = value(JOBID.1)
SMPDSN = "SMPE.*.OUTPUT.LISTINGS"
LISTC. = ''
SMPODSNS. = ''
SMPODSNS.0 = 0
$ = outtrap('LISTC.')
MSGVAL = msg('ON')
address TSO "LISTC LVL('"SMPDSN"') ALL"
MSGVAL = msg(MSGVAL)
$ = outtrap('OFF')
do LISTCi = 1 to LISTC.0
if word(LISTC.LISTCi,1) = 'NONVSAM' then
do
parse var LISTC.LISTCi . . DSN
SMPODSNS.0 = SMPODSNS.0 + 1
i = SMPODSNS.0
SMPODSNS.i = DSN
end
IX = pos('ENTRY',LISTC.LISTCi)
if IX <> 0 then
do
IX = pos('NOT FOUND',LISTC.LISTCi,IX + 8)
if IX <> 0 then
do
address ISPEXEC "SETMSG MSG(IPLL403E)"
EXITRC = 16
leave
end
end
end
LISTC. = ''
if EXITRC = 16 then
exit 0
address ISPEXEC "TBCREATE SMPDSNS NOWRITE" ,
"NAMES(TSEL TSMPDSN)"
I execute this code by typing %SMPSAVE next to the spool output line on the "H" SDSF panel and it runs fine until it gets to this point in the REXX:
114 *-* address ISPEXEC "TBCREATE SMPDSNS NOWRITE" ,
"NAMES(TSEL TSMPDSN)"
>>> "TBCREATE SMPDSNS NOWRITE NAMES(TSEL TSMPDSN)"
ISPS118S SERVICE NOT INVOKED. A VALID ISPF ENVIRONMENT DOES NOT EXIST.
+++ RC(20) +++
Does anyone know why it says I don't have a valid ISPF environment and how I can get around this?
I've done quite a bit in the past with REXX, including writing REXX code to handle line commands, but this is the first time I've tried to use ISPEXEC commands within this code.
Thank you,
Alan

Execute Process and Redirect Output

I run a process using VBScript. The process usually takes 5-10 minutes to finish and if i run the process standalone then it gives intermittent output while running.
I want to acheive the same logic while running the process using VBScript. Can some one please tell me how to do that?
Set Process = objSWbemServices.Get("Win32_Process")
result = Process.Create(command, , , intProcessID)
waitTillProcessFinishes objSWbemServices,intProcessID
REM How to get the output when the process has finished or while it is running
You don't have access to the output of processes started via WMI. What you could do is redirect the output to a file:
result = Process.Create("cmd /c " & command & " >C:\out.txt", , , intProcessID)
and read the file periodically:
Set fso = CreateObject("Scripting.FileSystemObject")
linesRead = 0
qry = "SELECT * FROM Win32_Process WHERE ProcessID=" & intProcessID
Do While objSWbemServices.ExecQuery(qry).Count > 0
Set f = fso.OpenTextFile("C:\out.txt")
Do Until f.AtEndOfStream
For i = 1 To linesRead : f.SkipLine : Next
WScript.Echo f.ReadLine
linesRead = linesRead + 1
Loop
f.Close
WScript.Sleep 100
Loop
The above is assuming the process is running on the local host. If it's running on a remote host you need to read the file from a UNC path.
For local processes the Exec method would be an alternative, since it gives you access to the process' StdOut:
Set sh = CreateObject("WScript.Shell")
Set p = sh.Exec(command)
Do While p.Status = 0
Do Until p.StdOut.AtEndOfStream
WScript.Echo p.StdOut.ReadLine
Loop
WScript.Sleep 100
Loop
WScript.Echo p.StdOut.ReadAll

How to check if $4 is registered in IRC?

I am quite an expert when it comes to programming in the MSL language, however I am unfamiliar with raw commands and whatnot.
I am in development of a new script. In this script I would like to check if $4 in what a user says is a registered nick or not but I do not know how to do this.
Thank you very much for any help and/or advice in advanced.
Best Regards,
Tim
Update:
raw 307:*:{ set $+(%,%chan,-,%CheckNick) Registered }
on *:TEXT:*:#:{
if ($1 == !regtest) {
set %chan $remove($chan,$chr(35))
set %CheckNick $4
whois $4
}
if ($($+(%,%chan,-,%CheckNick),$4),5) != $null) {
do this...
}
else {
else message...
}
}
I got this to work to check however my if statement to check if the variable has been set or not is being ignored...
Edit:
I tried using this:
checkNickReg $chan $2 $nick
...And echoing this:
echo -a Target: $1
echo -a Nick: $2
echo -a Status: $3
echo -a Chan: $3 - $chan
I'm trying to get a response to the channel such as; $nick $+ , $1 is not registered/registered/registered but not logged in.
What I've posted above is obviously wrong as it doesn't work, however I've tried a few methods and I'm actually not sure how the data is passed on with out the likes of tokenizing or setting variables...
Reply
[01:59:06] <~MrTIMarshall> !isReged mr-dynomite
[01:59:08] <&TornHQ> : mr-dynomite status is: NOTLOGGED
EDIT: mr-dynomite is not currently on, should this not = does not exist or does this check even when their not on, if so this is bloody brillant!!!
[02:00:04] <~MrTIMarshall> !isReged MrTIMarshall
[02:00:04] <&TornHQ> : MrTIMarshall status is: LOGGEDIN
$4 does not seem to work and what is the difference between 'exists, not logged in' and 'recognized, not logged in'?
Also, how does the data get passed on without setting variables or tokenizing?
(P.S. Thank you so much for the help you have dedicated so far!)
Another Edit:
I've been taking an in depth look today, am I correct in thinking if 0 or 1 the user is either not on-line or not registered (in the comments it says 0 = does not exists / not online, 1 = not logged in whereas 2 also says not logged in but recognized of which I'm unsure as what recognized means. Otherwise I'm very grateful for this script help and whatnot I'm just unclear on the numbers...
Since you have not specified any particular network I wrote an outline for some common networks around (that actually have user authentication systems). You should be able to add many other networks following the pattern.
Basically you execute /checkNickReg <target> <nick> [optional extra data] and when the server replays with the registration info (if applicable) use the on isReged signal event to handle the reply. Everything else is pretty much transparent.
EDIT: Looks like the specified network you are using (Torn) uses the standard anope services. So I updated the code to support that network.
; triggers when you get nick registration info back
; $1 = Target
; $2 = Nick
; $3 = Status, can be: LOGGEDIN, RECOGNIZED, NOTLOGGED
; $4- = Everything else passed
on *:signal:isReged:{
echo -a Target: $1
echo -a Nick: $2
echo -a Status: $3
echo -a Else: $4-
}
; reg lookup routines
alias checkNickReg {
set %reg. $+ $network 1
set %reg.target. $+ $network $1
set %reg.nick. $+ $network $2
set %reg.other. $+ $network $3-
; Freenode uses: NickServ ACC <nick>
if ($network == Freenode) msg NickServ ACC $2
; Rizon/SwiftIRC/OFTC/Torn use: NickServ STATUS <nick>
elseif ($istok(Rizon SwiftIRC OFTC Torn, $network, 32)) msg NickServ STATUS $2
}
; listen for replays
on *:notice:*:*:{
if ($($+(%, reg., $network),2)) {
;
var %target = $($+(%, reg.target., $network),2)
var %nick = $($+(%, reg.nick., $network),2)
var %other = $($+(%, reg.other., $network),2)
;
unset %reg*. $+ $network
if (($network == FreeNode) && ($2 == ACC)) $&
|| (($istok(Rizon SwiftIRC OFTC Torn, $network, 32)) && ($1 == STATUS)) {
; FreeNode:
; 0 = does not exist
; 1 = exists, not logged in
; 2 = recognized, not logged in
; 3 = logged in
; Rizon/SwiftIRC/OFTC/Torn:
; 0 = does not exists / not online
; 1 = not logged in
; 2 = recognized, not logged in
; 3 = logged in
if ($3 < 2) var %status = NOTLOGGED
elseif ($3 == 2) var %status = RECOGNIZED
else var %status = LOGGEDIN
}
;send status signal
.signal isReged %target %nick %status %other
}
}
(Extra Note: It might be useful to add an extra check to make sure $nick is AuthServ/NickServ for security reasons.)
A simple usage example is:
; Just a basic example of how to call it.
on *:text:!isReged &:#:{
checkNickReg $chan $2 $nick
}
on *:signal:isReged:{
msg $1 $4: $2 status is: $3
}
Type !isReged <nick>
Edit: The data gets passed to the on isReged event via global variables. I set them in the checkNickReg alias and I clean them up in the on notice event. So you never see them because they get cleaned up. They are passed to the isReged signal event in $1-.
On most IRCDs, it's only exposed in the WHOIS response for a user, if at all. Running a WHOIS every time a user says something is inadvisable, especially because server admins may receive a notification every time it happens.