Escape sequence for $ (dollar sign) in T-sql script - tsql

I am running a T-SQL script, called from a powershell script, that contains a text row which includes a sequence containing $(MV).
When I run the script I get the error "'MV' scripting variable not defined." which I assume is because it interpretates the $(MV) string as a variable instead of being a part of the text string.
How can I write the dollar sign as an escape sequence? Is that possible in a string?

Are you executing the script with sqlcmd? It will interpret $(variablename) and try to expand it.
You can disable this using the -x command-line option.
Oh, if you're using Invoke-Sqlcmd you can use the -DisableVariables parameter.
I was assuming you didn't want to have the sqlcmd variable substitution done. If you were just trying to get the $ past Powershell, use the back-tick (`$) as in another suggestion.

You can use the backtick character to escape a $ sign in PowerShell:
`$

Related

Run command line in PowerShell

I know there are lots of posts regarding this, but nothing worked for me.
I am trying to run this command line in PowerShell:
C:/Program Files (x86)/ClamWin/bin/clamd.exe --install
I have this in PowerShell:
&"C:/Program Files (x86)/ClamWin/bin/clamd.exe --install"
But all this does is execute clamd.exe, ignoring the --install parameter
How can I get the full command line to run?
Josef Z's comment on the question provides the solution:
& "C:/Program Files (x86)/ClamWin/bin/clamd.exe" --install # double-quoted exe path
or, given that the executable path is a literal (contains no variable references or subexpressions), using a verbatim (single-quoted) string ('...'):
& 'C:/Program Files (x86)/ClamWin/bin/clamd.exe' --install # single-quoted exe path
As for why your own solution attempt failed: The call operator, &, expects only a command name/path as an argument, not a full command line.
Invoke-Expression accepts an entire command line, but that complicates things further and can be a security risk.
As for why this is the solution:
The need for quoting stands to reason: you need to tell PowerShell that C:/Program Files (x86)/ClamWin/bin/clamd.exe is a single token (path), despite containing embedded spaces.
&, the so-called call operator, is needed, because PowerShell has two fundamental parsing modes:
argument mode, which works like a traditional shell, where the first token is a command name, with subsequent tokens representing the arguments, which only require quoting if they contain shell metacharacters (chars. with special meaning to PowerShell, such as spaces to separate tokens);
that is why --install need not, but can be quoted (PowerShell will simply remove the quotes for you before passing the argument to the target executable.)
expression mode, which works like expressions in programming languages.
PowerShell decides based on a statement's first token what parsing mode to apply:
If the first token is a quoted string - which we need here due to the embedded spaces in the executable path - or a variable reference (e.g., $var ...), PowerShell parses in expression mode by default.
A quoted string or a variable reference as an expression would simply output the string / variable value.
However, given that we want to execute the executable whose path is stored in a quoted string, we need to force argument mode, which is what the & operator ensures.
Generally, it's important to understand that PowerShell performs nontrivial pre-processing of the command line before the target executable is invoked, so what the command line looks like in PowerShell code is generally not directly what the target executable sees.
If you reference a PowerShell variable on the command line and that variable contains embedded spaces, PowerShell will implicitly enclose the variable's value in double quotes before passing it on - this is discussed in this answer to the linked question.
PowerShell's metacharacters differ from that of cmd.exe and are more numerous (notably, , has special meaning in PowerShell (array constructor), but not cmd.exe - see this answer).
To simplify reuse of existing, cmd.exe-based command lines, PowerShell v3 introduced the special stop-parsing symbol, --%, which turns off PowerShell's normal parsing of the remainder of the command line and only interpolates cmd.exe-style environment-variable references (e.g., %USERNAME%).

Run external PS commands with string

I want to run the CheckNetIsolation command from powershell that uses a string variable I have assigned earlier in the powershell script.
When I try
.\CheckNetIsolation loopbackexempt -d -n=$thePackage.PackageFamilyName
I think it takes the $thePackage.PackageFamilyName literally. I want the string it is assigned instead. How can I run this command with it using the string that variable is assigned to?
For me this should work
.\CheckNetIsolation "loopbackexempt" "-d" "-n=$($thePackage.PackageFamilyName)"
I just use double quotes as string delimiter for params and $() to get the value inside the string.

tcl exec to open a program with agruments

I want to open a text file in notepad++ in a particular line number. If I do this in cmdline the command should be:
start notepad++ "F:\Path\test.txt" -n100
And it is working fine from command line. Now I have to do this from tcl. But I can't make this command work with exec. When I try to execute this:
exec "start notepad++ \"F:\Path\test.txt\" -n100"
I am getting this error:
couldn't execute "start notepad++ "F:\Path\test.txt" -n100": no such file or directory.
What am I missing. Please guide.
Similar to this question:
exec {*}[auto_execok start] notepad++ F:/Path/test.txt -n10
First, you need to supply each argument of the command as separate values, instead of a single string/list. Next, to mimic the start command, you would need to use {*}[auto_execok start].
I also used forward slashes instead of backslashes, since you would get a first level substitution and get F:Path est.txt.
EDIT: It escaped me that you could keep the backslashes if you used braces to prevent substitution:
exec {*}[auto_execok start] notepad++ {F:\Path\test.txt} -n10
You can simply surround the entire exec statement in curly braces. Like this:
catch {exec start notepad++.exe f:\Path\test.txt -n10}
I haven't found a perfect solution to this yet. All my execs seem to be different from each other. On windows there are various issues.
Preserving double quotes around filename (or other) arguments.
e.g. in tasklist /fi "pid eq 2060" /nh the quotes are required.
Preserving spaces in filename arguments.
Preserving backslash characters in filename arguments.
[Internally, Windows doesn't care whether pathnames have / or \, but some programs will parse the filename arguments and expect the backslash character].
The following will handle the backslashes and preserve spaces, but will not handle double-quoted arguments. This method is easy to use. You can build up the command line using list and lappend.
set cmd [list notepad]
set fn "C:\\test 1.txt"
lappend cmd $fn
exec {*}$cmd
Using a string variable rather than a list allows preservation of quoted arguments:
set cmd [auto_execok start]
append cmd " notepad"
append cmd " \"C:\\test 1.txt\""
exec {*}$cmd
Note that if you need to supply the full path to the command to be executed, it often needs to be quoted also due to spaces in the pathname:
set cmd "\"C:\\Program Files\\mystuff\\my stuff.exe\" "

What's wrong with this Bitvise Tunnelier SFTP command?

I'm trying to put together an SFTP command to be run through Powershell. The executable I have access to is SFTPC.exe (Bitvise Tunnelier)
The command I'm trying is
sftpc.exe user#ftp.domain.com -pw=password -unat=y -cmd="ls \"somefile.txt\""
According to the documentation at https://www.bitvise.com/files/sftpc-v4.14-usage.txt this should log in and run the command ls "somefile.txt" (quotes are escaped within the command parameter)
What actually happens is that I get another line for input, as if there's an unclosed quote.
I've tried adding an extra quote to the end
sftpc.exe user#ftp.domain.com -pw=password -unat=y -cmd="ls \"somefile.txt\"""
This connects and logs in, but the colland it tries to run is ls \somefile.txt"
Note the trailing quote and the leading slash.
So it looks like I'm missing something in the quote escaping, but I can't see what I might be doing wrong. I've also tried replacing double quotes with single in a couple of different places, experiments that usually end in a syntax error.
The escape character in powershell is not a backslash, it's the backtick.
Does the below work?
sftpc.exe user#ftp.domain.com -pw=password -unat=y -cmd="ls `"somefile.txt`""

Single quotes and double quotes in perl

I'm a newbie in perl and I'm trying to execute an operating system command from a Perl script.
The operating system command is executed with IPC::Open3, and the command is like
$cmd = "mycommand --add \"condition LIKE '%TEXT%' \"";
This command is supposed to insert the string contained after the "add" into a database.
The problem is that it inserts the record in the database without the single quotes around %TEXT%, like this:
condition LIKE %TEXT%
If I execute the command at a command prompt it inserts the string correctly.
How should I format the double and single quotes so that it is inserted in the database correctly?
Thanks for the help
By putting the command in a single string, you are inflicting upon it a pass through your system's shell. (You don't mention if it's cmd.exe or bash or other fun stuff.)
Suggestions:
Creating your system command as an array of strings will avoid the shell re-interpolating your command line.
#cmd = ('mycommand', '--add', q(condition LIKE '%TEXT%'));
Throw in extra backslashes to protect the single quotes from your shell. Prepending echo to your command could help with the debugging....
(my personal favorite) Don't shell out for your Database access. use DBI.
$cmd = q{mycommand --add "condition LIKE '%TEXT%'"};
qq is for double-quoting , q is for single quoting.
This way it takes whole command as it is.