I am trying to run a bat file code from the following reference:
Detecting batch IP conflict
however, i am getting an error:
TRUE - invalid alias verb
-1 was unexpected at this time.
Could someone kindly explain this to me please. thanks. sample code attached below
#echo off
setlocal
:: Host to ping
set primary=x.x.x.1
:: Ping with options (1 ping sent per loop, wait 500 ms for timeout)
set ping_options=-n 1 -w 500
:: Fail over after x ping failed responses
set fail_limit=5
:loop
:: Ping x.x.x.1. Test for "reply from". If success, set failures=0; otherwise, increment failures
( ping %ping_options% %primary% 2>&1 | find /i "reply from" >NUL && set failures=0 ) || set /a "failures+=1"
:: If failures >= limit, switch IP
if failures GEQ %fail_limit% call :switch
:: Pause for a second and begin again.
ping -n 2 0.0.0.0 >NUL
goto loop
:: Switch subroutine
:switch
:: Get current IPv4 address
for /f "tokens=2 delims={}," %%I in ('wmic nicconfig where ipenabled="TRUE" get ipaddress /format:list') do set IP=%%~I
:: If the last character if the current IP is 1, switch to 2 (or vice versa)
if %IP:~-1%==1 ( set other=%IP:0,-1%2 ) else set other=%IP:0,-1%1
:: Perform the switch
netsh int ipv4 set address name="Local Area Connection" source=static address=%other% mask=255.255.255.0 gateway=none
All you need to do is escape the equal sign in the wmic command.
for /f "tokens=2 delims={}," %%I in (
'wmic nicconfig where ipenabled^="TRUE" get ipaddress /format:list'
) do set IP=%%~I
Related
I am tinkering around with ltk as it provides the option of running a remote GUI. However, when trying to use the remote GUI I run into issues I do not encounter when running ltk locally:
(in-package :ltk-user)
(defun add-current-investigation-frame (master)
(let* ((frame (make-instance 'frame :master master :width 100 :height 100))
(topic-label (make-instance 'label :text "Current Investigation" :master frame))
(project-label (make-instance 'entry :text "N/A" :master frame))
(action-button (make-instance 'button
:master frame
:text "new investigation")))
(setf (command action-button) (lambda ()
(format t "test~%")
(let ((next-project (nth (random 3) '("A" "B" "N/A"))))
(setf (text project-label) next-project))))
(pack frame)
(pack topic-label :side :top)
(pack project-label :side :top)
(pack action-button :side :top)))
(defun create-main-view ()
(let ((wrapper-frame (make-instance 'frame :master nil)))
(pack wrapper-frame)
(add-current-investigation-frame wrapper-frame)))
(defun create-remote-view (&optional (port 8888))
(Ltk:with-remote-ltk port ()
(create-main-view)))
(defun create-local-view ()
(with-ltk ()
(create-main-view)))
When running (create-local-view) everything works fine and the content of the entry widget changes randomly.
When running (create-remote-view) I get the error message can't read server: no such variable. Why does this error occur and how can I fix this?
I am using the remote.tcl deployed by quicklisp:
#!/usr/bin/wish
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
wm withdraw .
set host localhost
if {[llength $argv] == 2} {
set host [lindex $argv 0]
set port [lindex $argv 1]} else {
set port [lindex $argv 0]}
#puts "connecting to $host $port"
set server [socket $host $port]
set wi [open "|wish" RDWR]
fconfigure $server -blocking 0
fconfigure $wi -blocking 0
fileevent $server readable {set txt [read $server];puts $wi "$txt";flush $wi}
fileevent $wi readable {
if {[eof $wi]} {
close $wi
exit} else {
set txt [read $wi]; puts -nonewline $server $txt;flush $server}}
So I spent some time reading and testing the code, and it appears that it works better with remote-client.tcl than remote.tcl. When working with ltk-remote.lisp, the Lisp side creates a server that may accept multiple clients, each client being a tcl/tk interpreter.
lisp <=== socket stream ===> [ server socket ]
^
|
(wish interpreter)
The lisp side expects the interpreter to maintain a global variable named server. In the case of a local interpreter, this is done in init-wish, where there is set server stdout. In the case of a remote wish, it is expected that the wish interpreter sets this variable itself.
This is the case with remote-client.tcl, and the test applications works well (e.g. ltk-remote::lrtest), except that it adds a .status widget which is never removed. It should be possible to clean up a bit the remote-client.tcl script.
In the case of remote.tcl, the interpreter opens a pair of streams to another wish process:
set wi [open "|wish" RDWR]
It also connects to a server (variable server), and copies inputs from the server to the wish process. Unfortunately, the embedded wish process does not define a server variable:
lisp <=== socket stream ===> [ server socket ]
^
|
(wish interpreter 1)
"server" variable
|
"wi" variable
^
| pipe connection
v
(wish interpreter 2)
no "server" variable
If however you set server to stdout, as explained in the other answer, this assignment is evaluated in the second wish interpreter. The output is sent back to the first wish interpreter, which copies the answer back to the lisp server.
Instead of going through another wish interpreter, I tested locally by using a modified remote-client.tcl that doesn't add any widget:
package require Tk
set host localhost
set port 19790
set server ""
if {[llength $argv] > 0} {
set host [lindex $argv 0]
}
if {[llength $argv] > 1} {
set port [lindex $argv 1]
}
if {[catch {global server; global host; global port; set server [socket $host $port]}]} {
tk_messageBox -icon error -type ok -title "Connection failed!" -message "Cannot connect to server $host port $port."
exit
}
fconfigure $server -blocking 0 -translation binary -encoding utf-8
fileevent $server readable [list sread $server]
set buffer ""
proc getcount {s} {
if {[regexp {^\s*(\d+) } $s match num]} {
return $num
}
}
proc getstring {s} {
if {[regexp {^\s*(\d+) } $s match]} {
return [string range $s [string length $match] end]
}
}
proc process_buffer {} {
global buffer
global server
set count [getcount $buffer]
set tmp_buf [getstring $buffer]
while {($count > 0) && ([string length $tmp_buf] >= $count)} {
set cmd [string range $tmp_buf 0 $count]
set buffer [string range $tmp_buf [expr $count+1] end]
if {[catch $cmd result]>0} {
tk_messageBox -icon error -type ok -title "Error!" -message $result
puts $server "(error: \"$result\")"
flush $server
close $server
exit
}
set count [getcount $buffer]
set tmp_buf [getstring $buffer]
}
}
proc sread {server} {
global buffer
if {[eof $server]} {
tk_messageBox -icon info -type ok -title "Connection closed" -message "The connection has been closed by the server."
close $server
exit
} else {
set txt [read $server];
set buffer "$buffer$txt"
process_buffer
}
}
This is a preliminary answer as I am not entirely sure that this fix does not break anything. I will update this answer in the future to report back on encountered issues. But for now this fixes the issue.
In ltk.lisp there is a function called init-wish which requires an additional line (send-wish "set server stdout")
(defun init-wish ()
(send-lazy
;; print string readable, escaping all " and \
;; proc esc {s} {puts "\"[regsub {"} [regsub {\\} $s {\\\\}] {\"}]\""}
;(send-wish "proc esc {s} {puts \"\\\"[regsub -all {\"} [regsub -all {\\\\} $s {\\\\\\\\}] {\\\"}]\\\"\"} ")
;(send-wish "proc escape {s} {return [regsub -all {\"} [regsub -all {\\\\} $s {\\\\\\\\}] {\\\"}]} ")
(send-wish "package require Tk")
;;; PUT MISSING LINE HERE
(send-wish "set server stdout")
;;; PUT MISSING LINE HERE
(flush-wish)
#+:tk84
(send-wish "catch {package require Ttk}")
#-:tk84
(send-wish "if {[catch {package require Ttk} err]} {tk_messageBox -icon error -type ok -message \"$err\"}")
(send-wish "proc debug { msg } {
global server
puts $server \"(:debug \\\"[escape $msg]\\\")\"
flush $server
} ")
; more code ....
))
Explanation: The function seems to set up the wish interface and actions (confirmed by inserting prints in the remote.tcl). However, as one can see server is referenced in all procs yet it is never declared if we consider all those declarations to be in their own namespace. Consequently, the missing server has to be defined. As all the output is read by fileevent $wi ... and then passed on further, defining server as stdout seemed the most sensible.
It seems to work, however I have no clue if this breaks other stuff
I would like a command in a batch file to only execute if it has not been ran for the last 15 minutes. To achieve this I can create a "last_run" file to log the time last ran.
Where I am stuck is comparing the time last modified to the current time and taking action if the time last modified.
Here is my current code:
#echo off
set filename=last_run.txt
if not exist %filename% (
rem NOT EXISTS, CREATE FILE THEN PRINT THE LIST
echo.>"%filename%"
GOTO PrintList
) else (
rem FILE EXISTS, GET TIME LAST MODIFIED
FOR %%? IN (%filename%) DO (set filetime=%%~t?)
echo %filetime%
rem IF TIME LAST MODIFIED > 15 MINS PRINT THE LIST
if timediff??(%filetime%, current) > 15 mins {
GOTO PrintList
} else {
GOTO End
}
)
:PrintList
rem PRINT THE LIST
echo now print the list
rem WRITE TO THE FILE TO UPDATE TIME LAST MODIFIED
echo.>"%filename%"
GOTO End
:End
Another implementation using powershell from your batch-file:
#Echo Off
Set "filename=last_run.txt"
Set "minutes=15"
If Not Exist "%filename%" GoTo :PrintList
"%__APPDIR__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile If(((Get-Date)-(Get-Item ".\%filename%").LastWriteTime).Minutes -LT %minutes%){Exit 1}
If ErrorLevel 1 Exit /B
Rem Your payload below here.
:PrintList
CD.>"%filename%"
If you are happy to accept that the PC running this code will always have the appropriate entries in %PATH% and %PATHEXT%, you can change "%__APPDIR__%WindowsPowerShell\v1.0\powershell.exe" to just PowerShell.
Besides the missing time calculation, your code has a delayed expansion problem. (My solution below doesn't need delayed expansion)
cmd is incredibly crude when it comes to date/time calculation (it can be done, but...).
Better use the help of another language (like PowerShell):
#echo off
setlocal
set "filename=last_run.txt"
set "minutes=15"
if not exist "%filename%" (
break>"%filename%"
goto :PrintList
)
for /f %%a in ('"powershell Test-Path %filename% -OlderThan (Get-Date).AddMinutes(-%minutes%)"') do set "older=%%a"
if "%older%" == "True" (
echo %filename% is older than %minutes% minutes; print list
break>"%filename%"
goto :PrintList
) else (
echo %filename% is younger than %minutes% minutes; exiting
goto :eof
)
:PrintList
echo insert your payload here.
You could use total minutes with a powerhell command.
#echo off
set error=0
if not exist last_run.txt echo File not yet existed, first run will be now & set /a error+=1
for /f "delims=," %%i in ('powershell -command "(New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalMinutes"') do set "now=%%i"
if "%error%" == "1" goto :run
for /f %%a in (last_run.txt) do set earlier=%%a
set /a result=%now%-%earlier%
if %result% geq 15 (
:run
echo RUN COMMANDS HERE
echo %now%>tmp.tmp
)
The concept is simple. We get the epoch time in minutes. Store the value in a file. Then compare the current minutes with the minutes in the file. if %now% is equal to or more than 15 from %earlier% the command will run. Additionally, if the file does not yet exist, it will create it and run the command first time. From there it will only run if the seconds in the file is 15 or less than current minutes.
I need to validate whether DB connection is success/failure.
This is my code
report=`sqlplus -S /nolog << EOF
WHENEVER OSERROR EXIT 9;
WHENEVER SQLERROR EXIT SQL.SQLCODE;
connect <<username>>/<<Password>>#hostname:port
set linesize 1500
set trimspool on
set verify off
set termout off
set echo off
set feedback off
set heading on
set pagesize 0
spool extract.csv
<<My SQL Query>>
spool off;
exit;
EOF`
I have tried the below option based on the thread Managing error handling while running sqlplus from shell scripts but its picking the first cell value rather than the connection status.
if [ $report != 0 ]
then
echo "Connection Issue"
echo "Error code $sql_return_code"
exit 0;`enter code here`
fi
Please advise.
I needed something similar but executed it a bit differently.
First, I have list.txt which contains the databases that I would like to test. I am using wallet connections but this could be edited to hold username/password.
list.txt:
DB01 INSTANCE1.SCHEMA1
DB02 INSTANCE2.SCHEMA2
DB03 INSTANCE3.SCHEMA3
DB04 INSTANCE4.SCHEMA4
I have OK.sql which contains the query that I want to run on each database.
OK.sql:
select 'OK' from dual;
exit
Last, I user test.sh to read list.txt, attempt to connect and run OK.sql on each line, and record the result in (drumroll) result.txt.
test.sh:
. /etc/profile
rm result.txt
while read -r name wallet; do
echo "BEGIN-"$name
if (sqlplus -S /#$wallet #OK.sql < /dev/null | grep -e 'OK'); then
echo $name "GOOD" >> result.txt
else
echo $name "BAD" >> result.txt
fi
echo "END-"$name
done < list.txt
After the run check your result.txt.
result.txt:
DB01 BAD
DB02 GOOD
DB03 GOOD
DB04 GOOD
I hope this helps.
i have given a task to make a C-shell script. I have list of ip address and device name respectively. For example;
cal 1 : 100.21.25.10
cal 2 : 100.21.25.11
cal 3 : 100.21.25.12
cal 4 : 100.21.25.14
and so on...
Based on this ip and device name, i need to rsh the ip address and get the disk free of the device. The result of disk free will be save to a log. the details of the log will be have device name need to be housekeep. My idea is:
declared array :
set device =( cal1 cal2 cal3)
set ip = (100.21.25.10 100.21.25.11 100.21.25.12 100.21.25.14)
set highspace = 90
foreach data($ip)
set space = rsh $ip df -k
if (${space} >= ${highspace}) then
echo "Please Housekeep $device:" >> $device.log
endif
is this gonna work? Or do you guys have better idea? Thanks.
The C shell should never be used anymore. Neither should rsh; we have ssh now.
Your task in Bourne shell:
#! /bin/sh
highspace=90
fs_to_watch=/path/to/filesystem/that/fills/up
exec 0<"$1"
while read cal calno colon addr; do
space=$(ssh "$addr" df -k "$fs_to_watch" |
awk 'NR > 1 { sub(/%$/, "", $5); print $5 }')
if [ "$space" -gt "$highspace" ]; then
echo "Please Housekeep Cal-$calno"
fi
done
I was downloading MingW, and noticed that for a time the installer spawns a console window and downloads files. The intersting part is that it somehow creates download bars in the console window and overwrites the precentage number. I was wondering how this is accomplished?
NOTE:I am almost 100% sure the console is not writing '\n' out and is in fact overwriting the console.
I see Google was broken.
http://ss64.org/viewtopic.php?id=1499
The code:
#echo off
:: *****************************************************************************
:: * Script Name: DetectMSI_v1.0.cmd *
:: * Author: Gustaaf von Pickartz. *
:: * Date Created: 19th July, 2012. *
:: * Internal Version: Version 1.0 *
:: * ------------------------------------------------------------------------- *
:: * Notice: *
:: * This program is provided as is and for fair use distribution. *
:: * Give credit where credit is due to the author in your own script. *
:: * ------------------------------------------------------------------------- *
:: * Purpose: *
:: * Detect current active MSIEXEC instances using a function for repeatable *
:: * calls within a script and display a progress bar... *
:: * ------------------------------------------------------------------------- *
:: * Updated by: ------- *
:: * Date: 19-07-2012 *
:: * Change1: "Initial script version." *
:: * ------------------------------------------------------------------------- *
:: *****************************************************************************
SETLOCAL ENABLEDELAYEDEXPANSION
SET PRG0=[* ]
SET PRG1=[#* ]
SET PRG2=[##* ]
SET PRG3=[###* ]
SET PRG4=[####* ]
SET PRG5=[#####* ]
SET PRG6=[######* ]
SET PRG7=[#######* ]
SET PRG8=[########* ]
SET PRG9=[#########*]
SET PRG10=[##########]
:: Please note there are special ASCII insertions in the SET BKSPC= declaration below. 80x backspace characters are inserted. ASCII Value 08=[BS]
:: Be sure to verify they are still there when you cut and paste from the web with your text editor (Notepad++ or PsPad). Insert them if missing, otherwise this script will not work...
SET BKSPC=
:Begin_Main
:: For the sake of the demonstration, start MSIEXEC minimized.
START /MIN MSIEXEC
:: Call our function.
CALL :Fnc_Msi
:: Waste a little time...
PING -n 7 localhost >nul
ECHO Exited the FIRST MSIEXEC detection function and progress bar demo.
ECHO.
ECHO.
ECHO A function can't be a function if it cannot be re-used right?
:: For the sake of the demonstration, start MSIEXEC minimized.
START /MIN MSIEXEC
:: Call our function.
CALL :Fnc_Msi
ECHO Exited the SECOND MSIEXEC detection function and progress bar demo.
echo.
echo.
pause
GOTO :EOF
:: -----------------------------------------------------------------------------
:: Below code is setup to run as a Function to be called anywhere in your script.
:: It will wait 10 loops at 7 sec intervals anytime it is called. Primarily written to detect active MSI installers.
:: The Menu counter and Progress bar is in the function for fun.
::
:: Usage: CALL :Fnc_Msi
2
:Fnc_Msi
CALL ECHO [.....] %%date%% %%time%% Testing for active MSI instances.
:catchit
IF NOT DEFINED CatchMSI SET CatchMSI=0
IF %CatchMSI% EQU 5 (
ECHO Waited 5 loops {15sec.} to detect MSI activities. Now resuming further MSI evaluation.
goto evalmsi
)
FOR /F "TOKENS=2* DELIMS=:" %%I IN ('TASKLIST /V /FI "IMAGENAME EQ MSIEXEC.EXE" /FO LIST 2^>NUL ^|FIND /I /V "N/A" ^|FIND /I "WINDOW TITLE:"') DO (SET MSI=%%I)
IF DEFINED MSI SET MSI_APP=%MSI:~1%
IF DEFINED MSI_APP goto msi_active
>NUL PING -n 3 localhost
SET /A CatchMSI+=1
goto :catchit
:evalmsi
IF NOT DEFINED MSI_APP (
ECHO [OKAY.] No active MSIEXEC installer running. It is safe to continue.
SET CatchMSI=
SET MSI_APP=
SET CNT=
SET COUNT=
SET TIC=
GOTO :EOF
)
:msi_active
SET CNT=0
ECHO [ALERT] Installer "%MSI_APP%" is active. Waiting maximum 10 counts.
:loop
IF NOT DEFINED COUNT SET COUNT=0
IF %COUNT% LEQ 9 (SET TIC=0%COUNT%) ELSE (SET TIC=%COUNT%)
IF %count% EQU 10 (
<NUL (SET/P Z=[%tic%/10] PROGRESS: !PRG%CNT%!)
:: Feel free to adjust the PING -n 3 value to say 30sec waits.
>NUL PING -n 3 localhost
TASKKILL /F /FI "WINDOWTITLE eq %MSI_APP%*" >>myprogress.log
<NUL SET/P Z=%BKSPC%
SET MSI_APP=
SET CatchMSI=
SET MSI_APP=
SET CNT=
SET COUNT=
SET TIC=
GOTO :EOF
)
<NUL (SET/P Z=[%tic%/10] PROGRESS: !PRG%CNT%!)
:: Feel free to adjust the PING -n 3 value to say 30sec waits.
>NUL PING -n 3 localhost
<NUL SET/P Z=%BKSPC%
:: Here we write to a log file and call tasklist.exe to do interval checks on the MSIEXEC status.
:: Demonstrated is that the progress bar is not affected when code is run in the loop.
:: Do keep in mind to "suppress to >nul 2>nul" any output that may disrupt the progress bar activty.
ECHO [%tic%/10] Waiting for "%MSI_APP%" to complete. >>myprogress.log
TASKLIST.EXE /V | FIND /I "%MSI_APP%">NUL 2>NUL
IF %ERRORLEVEL% EQU 1 (
>NUL PING -n 7 localhost
SET CatchMSI=
SET MSI_APP=
SET CNT=
SET COUNT=
SET TIC=
GOTO :EOF
)
SET /A CNT+=1
SET /A COUNT+=1
goto loop
GOTO :EOF
:: -----------------------------------------------------------------------------
Credit is obviously due to the original author.