Trying to execute a command inside a batch file and drop the result into a variable.
Here's what I would execute interactively:
curl -d "username=someUser" http://someServer/trusted
The result is a 15-20 character alpha-numeric string.
Here's my attempt at doing same in a batch file:
FOR /f %AA IN('curl -d \"username=someUser\" http://someServer/trusted') DO ECHO %AA
Error returned is:
//someServer/Trusted') was unexpected at this time
I thought I was dealing with some sort of escaping issue, so I added the \ symbols in front of my quotes. From what I've read, the : symobol in http doesn't need to be escaped, but it's interesting to me that's where the failure appears to "start".
Any ideas on this? I'm on Win8.1, FYI
for-variables have one-char-variables (%A instead of %AA)
you missed a space between IN and (
in a batch-file you have to double the percent-signs for the for-variable (%%A instead of %A)
echo handles only one line, blanks brake it, you would need to pipe it maybe?
Related
Good Day All!
I have a batch script, and when I echo a variable like this
echo %variable1%
I get out put like this
TestLine1
TestLine2
TestLine3
TestLine4
My goal would be to modify this variable to remove all the newline characters so the output would look more like
TestLine1TestLine2TestLine3TestLine4
Is there a simple way to do this without creating files?
Thank you for your assistance.
You can use the command tr:
cleanedVariable1=$(echo $variable1 | tr -d '\n' )
echo $cleanedVariable1
The command tr removes or translates characters. The option -d removes the given characters. In this case, we are removing all new lines from our variable and assign it to a new variable.
I'm trying to create a batch program (here called pldl) to make downloading a playlist of songs with youtube-dl easier, the program is
youtube-dl -o "%(playlist_index)s. %(title)s.%(ext)s" -x --audio-format "mp3" %1
which is supposed to just take the first argument (%1) and add it to this long command, so running command_name "playlist_url" would download it in the location I ran it. Unfortunately, it throws an error instead (echo is on for debugging)
E:\Path\To\Music>pldl "https://www.youtube.com/playlist?list=PLSdoVPM5WnndV_AXWGXpzUsIw6fN1RQVN"
E:\Path\To\Music>youtube-dl -o "(title)s.1
Usage: youtube-dl [OPTIONS] URL [URL...]
youtube-dl: error: You must provide at least one URL.
Type youtube-dl --help to see a list of all options.
E:\Path\To\Music>
What's going on here? Why is the command not run properly as seen in the echo? Also is there possible a better way of doing this (tying a long command with argument to a short name) sorry for the low quality post just need this fast.
The script-parser tries to expand the variables:
%(playlist_index)s. %
%(ext)s" -x --audio-format "mp3" %
Which are likely undefined. Because there is nothing to expand, part of the command-line parameter is stripped before being passed to the youtube-dl program. Use double percent signs instead:
youtube-dl -o "%%(playlist_index)s. %%(title)s.%%(ext)s" -x --audio-format "mp3" "%~1"
Quoting and escaping
The percent sign (%) is a special case. On the command line, it does
not need quoting or escaping unless two of them are used to indicate a
variable, such as %OS%. But in a batch file, you have to use a double
percent sign (%%) to yield a single percent sign (%). Enclosing the
percent sign in quotation marks or preceding it with caret does not
work.
Is it possible to write the same output to more than one file in Batch?
My reason for wanting to do this is because I have a large batch script that produces a very detailed log. This is fine as it is, but i want to also output a trimmed back version of the log with a lot less detail in it. The Batch cannot be run multiple times either.
Say for instance I have a simple batch:
Echo This is a Batch Script >> Path\File1 & Path\File2
osql -S%SERVERNAME% -E -d%DATABASENAME% -Q%SQL% >> Path\File1
Appreciate any help.
Maybe you can use the tee command from Unix tools. Downloadable for free from here. Think of it like a "T" that a plumber might put in a pipe to send water two ways.
osql -S%SERVERNAME% -E -d%DATABASENAME% -Q%SQL% | tee file1 file2 file3
Have a look at some examples as I am not entirely sure what your full processing requirement is, see here.
If you want to do some processing on one stream you can do this:
osql -S%SERVERNAME% -E -d%DATABASENAME% -Q%SQL% | tee unfiltered.txt | FINDSTR /v "UglyStuff" > filtered.txt
Second answer, because it is different...
You could use some VBScript, like this to send your osql output to both stdout and stderr and then handle the two separately. This saves you needing to install any Unix tools.
Save this as tee.vbs
REM ############################################################################
REM File: tee.vbs
REM Author: Mark Setchell
REM I don't need any Unix purists to tell me it is not functionally idential to
REM the Unix 'tee' command, please. It does a job - that's all. And I also know
REM there is no error checking. It illustrates a technique.
REM ############################################################################
Set fso = CreateObject ("Scripting.FileSystemObject")
Set stdout = fso.GetStandardStream (1)
Set stderr = fso.GetStandardStream (2)
Do While Not WScript.StdIn.AtEndOfStream
REM Read in next line of input
Line = WScript.StdIn.ReadLine()
stdout.WriteLine(Line)
stderr.WriteLine(Line)
Loop
Then run your osql like this:
osql -S%SERVERNAME% -E -d%DATABASENAME% -Q%SQL% | cscript /nologo tee.vbs 2> unfiltered.txt | FINDSTR "goodstuff" > filtered.txt
Basically, whatever the tee.vbs script writes to stderr gets redirected to wherever 2> points, and whatever tee.vbs writes to stdout goes into the FINDSTR command.
Ideally, you could put your filtering inside the tee.vbs file for maximum flexibility.
I am working on NSCA to integrate passive alerts and checks from remote machines and applications with Nagios. On the internet, I have found a part of batch file code which could help perform it. However I don't understand the use of the pipe at the last line. I know how the pipe works but I cannot see how the output echo %1;%2;%3;"%4" will be using as input of values %NSCA_BIN% -H %NSCA_SERVER% -p 5667 -to 10 -c %NSCA_CFG% -d ; .
set NSCA_HOME="D:\Nagios\BIN\GATEWAY"
set NSCA_BIN=%NSCA_HOME%\send_nsca.exe
set NSCA_CFG=%NSCA_HOME%\send_nsca.cfg
set NSCA_SERVER="192.168.10.110"
echo %1;%2;%3;"%4" | %NSCA_BIN% -H %NSCA_SERVER% -p 5667 -to 10 -c %NSCA_CFG% -d ;
Can you enlighten to clarify this point (about the meaning of the use of this pipe) for me please?
Thanks in advance
In this case, it looks like D:\Nagios\BIN\GATEWAY\send_nsca.exe takes input from the user when run from a command line. This script uses the values in %1 - %4 as the inputs as if the user had typed it.
The variables %1, %2, %3, and %4 are the first four space-delimited arguments provided on the command line to the script.
The part after the pipe evaluates to:
D:\Nagios\BIN\GATEWAY\send_nsca.exe -H 192.168.10.110 -p 5667 -to 10 -c D:\Nagios\BIN\GATEWAY\send_nsca.cfg -d ;
Documentation for send_nsca says that it takes data from standard input consisting of Nagios Service Host, Nagios Service Description, Status Number, and Plugin Output separated by tabs or a delimiter specified with the -d switch. The command above sets the delimiter to ;.
The part before the pipe, echo %1;%2;%3;"%4", takes the four command line arguments, separates them with colons, quotes the last one, and feeds them as input to send_nsca. That means you'd call the script like this:
scriptname.bat NagiosServiceHost NagiosServiceDescription StatusNumber PluginOutput
The purpose of the script appears to be to save you the trouble of having to type out the path to send_nsca and all the command line arguments, and simply provide the input, which is useful if you use this command multiple times.
I seems to me, though, that there's an error in the way the batch file is written. Nothing I see in the docs specifies that the fourth field of the input (plugin output) needs to be quoted, so I presume that the idea behind quoting %4 is to allow the plugin output specified on the command line to contain spaces. However, this won't work, because the batch file assigns space-delimited tokens from the command line to the %# variables, so %4 will only contain the fourth token, and everything after a space that follows it will be ignored.
I think the quotes should be taken out, and if you need to supply an argument with spaces, quote it on the command line at the time you invoke the batch file, like this:
scriptname.bat NagiosServiceHost NagiosServiceDescription StatusNumber "Plugin Output With Spaces"
This would set %4 to "Plugin Output With Spaces" (yes, the quotes are included in the value of the variable -- which is what you want).
I have a shell script that I want to execute this line:
qtvars.bat vsstart "qt.sln" /BUILD "Debug|Win32"
This works fine (though I had to modify qtvars.bat, but that's beside the point). The problem is that I want the command to execute to be in a variable:
EDIT: This doesn't work either, if I type it into bash. Previously I was typing it into cmd.exe, which hardly made for a fair comparison.
command="qtvars.bat"
args="vsstart"
$command $args "qt.sln" /BUILD "Debug|Win32"
Now it chokes on the pipe! I get this message:
'Win32' is not recognized as an internal or external command,
operable program or batch file.
I've tried a bunch of forms of escaping the quotes and/or pipe, all to no avail. Interestingly, it works when it's an executable rather than a batch file, e.g.:
command="devenv.exe"
args=""
$command $args "qt.sln" /BUILD "Debug|Win32"
Thanks for any ideas.
I know you "escape" the pipe character in a batch file with the ^ character, so...
echo ^| Some text here ^|
Would display...
| Some text here |
I don't know whether that would help you in this instance? Maybe try prepending each pipe character with a ^ and see what happens? :-)
This is a classic case of double-escaping, where both bash and CMD.EXE need to be instructed to ignore the special | (pipe) character.
Try the following:
$command $args "qt.sln" /BUILD '"Debug|Win32"'
This will be the equivalent of you typing, at a CMD.EXE prompt:
qtvars.bat vsstart qt.sln /BUILD "Debug|Win32"
Using the above, you are essentially forcing the passing of the double-quotes on to CMD.EXE (instead of bash eating them away.) The outermost single quotes instruct bash not to interpret or touch in any way what's inside them; the inner double-quotes instruct CMD.EXE to ignore any special characters (the pipe in this case) within.
Alternatively, you can also try:
$command $args "qt.sln" /BUILD 'Debug\|Win32'
This should be the equivalent of you typing, at a CMD.EXE prompt:
qtvars.bat vsstart qt.sln /BUILD Debug\|Win32
Note the use of single quotes (!), which ensure that bash will not interpret the \ (and, instead, will pass it as-is to CMD.EXE.)
Here's another solution (workaround?) I've found:
first, ensure an environment variable defines the pipe character, for example:
set PIPE="|"
later, run the command specifying the above defined environment variable name:
"c:\(...)\devenv.com" foo.sln /build Debug%PIPE%Win32
That does the job even if there are multiple wrappers between the caller and the callee. I'm now using it with a very long chain of wrappers:
Python/Linux -> VirtualBox guest's executeProcess -> Cmd/Windows -> devenv.com
(cross posted to: How to pass a quoted pipe character to cmd.exe?)
Escaping a piping character in the Windows scripting language is done with a caret (^). I just had to do this the other day. I know this is old, but I thought I would post what I found in case others ran across this, like I did.
I'd consider going the easy route, and passing a placeholder-token instead - "$P", and then replace it within the CMD/Batch file; e.g. using the 'UnxUtils' SEd command to do the replacement:
For /F "usebackq delims=" %%r in (`Echo %Cmd% ^| sed -e "s/$P/|/g"`) do #Set Cmd2=%%r
REM Now run the command, with the proper pipe symbol in place
%Cmd2%
So having passed the command arg/CMD script args - "git status $P wc -l".
Interesting! What does escaping the | do?
Do these work?
echo "Debug|Win32"
echo "qt.sln" /BUILD 'Debug|Win32'