In this NT cmd shell\"batch file" I scrabbled together the other day, I'm using the call command to run sections of the script like functions--as I have done many times before in other scripts. But one of this is behaving strange and I can't figure out what might be wrong...
The problem is that the first time the function is called it properly returns the errorcode and sets the (global) variable %RESULT%, but every time it's called again later it fails to update the variable with the new errorcode.
Here's a stripped-down version of the code in question:
:FACL
REM run fileacl.exe with given OPTIONS (%1)
REM uses global variables %TARGET% and %LOGPATH%, sets global %RESULT%
setlocal
set _OPTIONS_=%*
fileacl.exe "%TARGET%" %_OPTIONS_% /SILENT >%LOGPATH%\temp.out 2>%LOGPATH%\temp.err
set _RESULT_=%ERRORLEVEL%
if defined DEBUG echo INSIDE FUNCTION: _RESULT_ = %_RESULT_%
endlocal & set RESULT=%_RESULT_% & goto :EOF
The function is called in lines like this:
call :FACL /LINE
if defined DEBUG echo AFTER TEST #1: RESULT = %RESULT%
...
call :FACL /INHERIT /REPLACE /FORCE
if defined DEBUG echo AFTER FIX #2: RESULT = %RESULT%
You see those if defined DEBUG... lines there? They show me that inside the function, subsequent calls are succeeding and thus printing out the expected %_RESULT_% of 0, but the global %RESULT% remains the same. Here's some example output:
TEST #1:
INSIDE FUNCTION: _RESULT_ = 107 <-- that's what I expect for the first call
AFTER TEST #1: RESULT = 107 <-- the variable was properly set after the first call
FIX #2:
INSIDE FUNCTION: _RESULT_ = 0 <-- command succeeded :)
AFTER FIX #2: RESULT = 107 <-- variable didn't change :(
RETEST:
INSIDE FUNCTION: _RESULT_ = 0 <-- succeeded again
AFTER RETEST: RESULT = 107 <-- still didn't change
You may ask: what else have you tried? Okay:
Removed the setlocal\endlocal tricks and just used the global %RESULT% variable
Explicitly undefined %RESULT% and %_RESULT_% (e.g. set RESULT=) before each time the function is called
...all with the same results. Is there something I'm missing here?
Can't be sure, because we can't see the actual code in context. But the behavior you are describing is to be expected if the FIX 2 CALL and ECHO are within a parenthesized block - perhaps as part of an IF statement or FOR loop.
If that is the case, then you need to use delayed expansion within the parentheses since the entire block is parsed prior to execution and the %RESULT% is expanded at parse time.
Use SET EnableDelayedExpansion to enable delayed expansion, and use !RESULT! instead of %RESULT% to get the value of RESULT at execution time instead of at parse time.
Related
I'm relatively new to using Octave. I'm working on a project that requires me to collect the RGB values of all the pixels in a particular image and compare them to a list of other values. This is a time-consuming process that takes about half a minute to run. As I make edits to my code and test it, I find it annoying that I need to wait for 30 seconds to see if my updates work or not. Is there a way where I can run the code once at first to load the data I need and then set up an artificial starting point so that when I rerun the code (or input something into the command window) it only runs a desired section (the section after the time-consuming part) leaving the untouched data intact?
You may set your variable to save into a global variable,
and then use clear -v instead of clear all.
clear all is a kind of atomic bomb, loved by many users. I have never understood why. Hopefully, it does not close the session: Still some job for quit() ;-)
To illustrate the proposed solution:
>> a = rand(1,3)
a =
0.776777 0.042049 0.221082
>> global a
>> clear -v
>> a
error: 'a' undefined near line 1, column 1
>> global a
>> a
a =
0.776777 0.042049 0.221082
Octave works in an interactive session. If you run your script in a new Octave session each time, you will have to re-compute all your values each time. But you can also start Octave and then run your script at the interactive terminal. At the end of the script, the workspace will contain all the variables your script used. You can type individual statements at the interactive terminal prompt, which use and modify these variables, just like running a script one line at the time.
You can also set breakpoints. You can set a breakpoint at any point in your script, then run your script. The script will run until the breakpoint, then the interactive terminal will become active and you can work with the variables as they are at that point.
If you don't like the interactive stuff, you can also write a script this way:
clear
if 1
% Section 1
% ... do some computations here
save my_data
else
load my_data
end
% Section 2
% ... do some more computations here
When you run the script, Section 1 will be run, and the results saved to file. Now change the 1 to 0, and then run the script again. This time, Section 1 will be skipped, and the previously saved variables will be loaded.
I'm trying to capture exit code from an ssis execute process task into a variable. The exit code is a string, although the value itself is an integer, value of 0 or 1 is success, other mean failure.
As far as I know I cannot specify multiple success values within the "Success value property", so I decided to capture the exit code into a variable, pass it to Execute script task and evaluate there whether the exit code represents success or failure.
I've set up a string variable to capture the exit code of my app, with type string.
Unfortunately, the value is empty after Process task execution, no matter whether I put my variable directly into StandardOutputVariable or into Expressions tab:
On execution, in the Locals windows in debug mode I see the value is empty (e.g. {}).
Is there a way to overcome this?
I'd appreciate any feedback.
Whatever you are capturing in the variable, is not the exit code. It is the output value (StandardOutput).
For getting the exit code, what you have to do is, in the command arguments, add the below suffix
Executable: cmd.exe
Arguments: /C mycmd_with_parameters;echo %ERRORLEVEL%
%errorlevel% will be having the exit code of the executable. You are outputting that to standard output. More info on %Errorlevel%
There is one caveat:
When an external command is run by CMD.EXE, it will detect the
executable's Return or Exit Code and set the ERRORLEVEL to match. In
most cases the ERRORLEVEL will be the same as the Exit code, but there
are some cases where they can differ.
An Exit Code can be detected directly with redirection operators
(Success/Failure ignoring the ERRORLEVEL) this can often be more
reliable than trusting the ERRORLEVEL which may or may not have been
set correctly.
Now, you will get the exitcode of the executable as standardoutput and you can capture it to the variable, as you have configured.
The StandardOutputVariable of an Execute Process Task contains the terminal output. So, if you are using a bash executable, all ECHO results should be saved on that variable.
You can check the variable values during runtime debug.
Problem
I'm writing a Julia script, and in the function there is a while loop. Inside the while loop there is a variable. That line is throwing errors about the variable being undefined when in fact that is the very line defining the variable.
The code
The error is on line 65
function cleanTexLoop(fileName::String)
f = open(fileName, "r")
while ! eof(f)
line = readline(f), <-- line 65
#line = sentenceFilter(line)
println(line)
end
close(f)
end
The function opens a file which IS getting passed into a loop. The loop runs until the end of file. While looping the file is read line by line. Each time it is read the line is stored in variable line and the file advances. In the proper version, that one line (66) isn't commented out, however for debugging it is. line is then taken as input into a filter which modifies the line before storing it again as line. The final version of this script will have four filters, but for now, I'd be happy to get this to run with just zero filters.
(Note that a user has kindly pointed out the comma that after hours of looking at the code continued to allude me. I'm waiting for that user to write up an answer)
The error message
cleanTexLoop("test.tex")
ERROR: UndefVarError: line not defined
Stacktrace:
[1] cleanTexLoop(::String) at /home/nero/myScripts/latexCleaner.jl:65
[2] macro expansion at ./REPL.jl:97 [inlined]
[3] (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at > ./event.jl:73
Previous working version
I had previous written another version of this which works in entirety, however I needed to make some substantial changes to its structure in order to better suit future plans. Note that some of the names aren't up to the normal naming convention. Namely, I use "!" when no variables are actually being changed.
function CleanTexLoop(fileName::String,regX::String,sub::String)
f = open(fileName, "r")
while ! eof(f)
println(applySub!(f,regX,sub))
end
close(f)
end
function applySub!(file::IOStream,regX::String,sub::String)
return replace(
readline(file),
Base.Regex(regX),
Base.SubstitutionString(sub)
)
end
A simple loop which demonstrates why this should work
x = 0
while x < 4
y = x
println(y)
x = x+1
end
As expected, this prints zero to one, and is, as far as I can tell, representative of what I am doing. In both cases I am passing some variable into the loop which, through some action, defines another variable inside the loop which is then printed. Why this works, and the other doesn't is beyond me.
What I've seen on Google.
From looking this problem up, it appears as if this problem arrises when defining variables outside of a loop, or similar environment, as a result of them failing to be passed into the environment. However, this isn't what's happening in my case. In my case the variable is being defined for the first time.
As mentioned in the comments, the problem was an errant comma.
I am running a shell script which emits lots of line while executing...they are just status output rather than the actual output....
I want them to be displayed on a JTextArea. I am working on jython. The piece of my code looks like:
self.console=JTextArea(20,80)
cmd = "/Users/name/galaxy-dist/run.sh"
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
self.console.append(p.stdout.read())
This will wait until the command finishes and prints the output. But I want to show the realtime out put to mimic the console. Anybody have the idea ?
You're making things more complicated than they need to be. The Popen docs state the following about the stream arguments:
With the default settings of None, no redirection will occur; the child’s file handles will be inherited from the parent. [my emphasis]
Therefore, if you want the subprocess' output to go to your stdout, simply leave those arguments blank:
subprocess.Popen(cmd, shell=True)
In fact, you aren't using any of the more advanced features of the Popen constructor, and this particular example doesn't need any parsing by the shell, so you can simplify it further with the subprocess.call() function:
subprocess.call(cmd)
If you still want the return code, simply set a variable equal to this call:
return_code = subprocess.call(cmd)
I want to have keyboard shortcut in Vim to copy a whole function from a Powershell file to the Windows clipboard. Here is the command for it:
1) va{Vok"*y - visual mode, select {} block, visual line mode, go to selection top, include header line, yank to Windows clipboard.
But it would work only for functions without an inner {} block. Here is a valid workaround for it:
2) va{a{a{a{a{a{a{Vok"*y - the same as (1), but selecting {} block is done multiple times - would work for code blocks that have 7 inner {} braces.
But the thing is - the (1) command works fine when called from a vim function, but (2) misbehaves and selects wrong code block when called from a vim function:
function! CopyCodeBlockToClipboard ()
let cursor_pos = getpos('.')
execute "normal" 'va{a{a{a{a{a{a{Vok"*y'
call setpos('.', cursor_pos)
endfunction
" Copy code block to clipboard
map <C-q> :call CopyCodeBlockToClipboard()<CR>
What am I doing wrong here in the CopyCodeBlockToClipboard?
The (2) command works as expected when executed directly in vim.
UPDATE:
I've noticed that:
if there are more a{ then the included blocks in the function
then vim wouldn't execute V
Looks like vim handles errors differently here. Extra a{ produces some error and regular command execution just ignores it. But execution from withing a function via :normal fails and wouldn't call V (or probably any command that follows the error).
Any workaround for this?
Try this function
function! CopyCodeBlockToClipboard()
let cursor_pos = getpos('.')
let i = 1
let done = 0
while !done
call setpos('.', cursor_pos)
execute "normal" 'v' . i . 'aBVok"*y'
if mode() =~ "^[vV]"
let done = 1
else
let i = i + 1
endif
endwhile
execute "normal \<ESC>"
call setpos('.', cursor_pos)
endfunction
This preforms a execute command to select blocks until it fails to select a block larger block. ([count]aB selects [count] blocks) It seems when the selection fails we end up in visual mode. So we can use mode() to check this.
When this function exits you should be in normal mode and the cursor should be restored to where you started. And the function will be in the * register.
This macro should come close to what you want to achieve:
?Function<CR> jump to first Function before the cursor position
v enter visual mode
/{<CR> extend it to next {
% extend it to the closing }
"*y yank into the system clipboard