why does $ssh->exec(..) doesn't execute when we have dynamic variables as part of command - phpseclib

I am unable to run the below command when i pass the values as $start & $end but it runs successfully when i give the date values directly. Is there any other way of running the command?
Note : I am using phpseclib and able to successfully login and execute basic commands.
$start value is "2015-07-27 18:48:56"
$end value is "2015-07-27 18:49:00"
echo $ssh->exec('/tpo/umc/bin/cmu_monitoring_dump -n r02bv01 -m cpunumber -t0 "$start" -t1 "$end" -f line> /tmp/adwant.txt');

The short answer is that you cannot nest double and single quoted strings, which appears to be what you're trying to do here and expecting the result to be that PHP will expand your variables into the string. Once the string syntax begins with single quotes, no characters inside of the string will be expanded (re-evaluated), which is unlike double quotes. So double quote inside of a single quoted string is still just a literal double quote.
Instead use echo $ssh->exec("/tpo/umc/bin/cmu_monitoring_dump -n r02bv01 -m cpunumber -t0 $start -t1 $end -f line> /tmp/adwant.txt");
The Long Answer
In PHP there are 4 main syntax for strings (since PHP 5.3, anyway).
Double Quoted Strings
Single Quoted Strings
Heredoc
Nowdoc
Heredoc and Nowdoc syntax will produce the same net result as Double and Single quoted strings, respectively.
The only difference between single and double quote strings is that single quote strings do no offer string interpolation and only have one escape sequence character (the single quote itself). That is to say, that when you create a string like 'some $string here' it will become a string literal of every character between the opening and closing single quote with no other characters that can be expanded within the string. Same thing applies to Nowdoc string syntax.
Caveats
Now, assuming you want literal double quotes in the string you need to escape those with a backslash \ escape character. See escaping double quote strings in the manual.
You should also note that there is a difference in some shells between double and single quotes as well, outside of PHP's string parsing, and that those shells may have different escape sequence characters as well (see escapeshellarg for more details).

Related

powershell -replace: surround captured regex group with dollar signs like: $group$

I want to replace strings like url: `= this.url` with url: $url$
I got quite close with this:
(Get-Content '.\file') -Replace "``= this.(\w+)``", "$ `$1$"
with output url: $ url$.
But when I remove extra space then the output breaks.
How can I escape/modify "$`$1$" so that it works?
You can use
-Replace "``= this\.(\w+)``", '$$$1$$'
Note that
The . must be escaped in the regex pattern
'$$$1$$' is a $$$1$$ string that contains:
$$ - a literal single $ char
$1 - the backreference to the first capturing group
$$ - a literal single $ char.
Powershell 7 version of -replace with a scriptblock 2nd argument. Just assigning $_ into $a to look at it. Note the backquote is a special character inside doublequotes, which I'm avoiding.
'url: `= this.url`' -replace '`= this\.(\w+)`', {$a = $_; '$' + $_.groups[1] + '$'}
url: $url$
$a
Groups : {0, 1}
Success : True
Name : 0
Captures : {0}
Index : 5
Length : 12
Value : `= this.url`
ValueSpan :
tl;dr
# * Consistent use of '...', obviating the need to `-escape ` and $
# * Verbatim $ chars. in the substitution string escaped as $$
# * Capture-group reference $1 represented as ${1} for visual clarity.
(Get-Content .\file) -replace '`= this\.(\w+)`', '$$${1}$$'
Background information and guidance:
In the substitution operand of PowerShell's regex-based -replaceoperator, a verbatim $ character must be escaped as $$, given that $-prefixed tokens have special meaning, namely to refer to results of the regex matching operation, such as $1 in your command (a reference to what the 1st, unnamed capture group in the search regex captured).
Unlike what the docs partially suggest, such a substitution string is not itself a regex, and any other characters are used verbatim.
To programmatically escape $ for verbatim use in a substitution string, it's simplest to use the .Replace() .NET string method, which performs _verbatim (literal) replacements (assuming that all $ instance are to be escaped; e.g. '$foo$'.Replace('$', '$$')
Note that, situationally, a capture-group reference such as $1 may need to be disambiguated as ${1}, and you may always choose to do that for visual clarity, as shown above.
It is only the search operand is a regex, and there all characters that are regex metacharacters must be \-escaped in order to be used verbatim, which can be done:
character-individually, in string literals (amount: \$)
programmatically, for entire strings, using [regex]::Escape() ([regex]::Escape('amount: $'))
To avoid confusion over up-front string interpolation by PowerShell vs. what the .NET regex engine ends up seeing, it's best to consistently use verbatim (single-quoted) strings ('...') rather than expandable (double-quoted) strings ("...").
If embedding PowerShell variable values is needed, use techniques such as:
string concatenation ('^' + [regex]::Escape($foo) + '$')
or -f, the format operator ('^{0}$' -f [regex]::Escape($foo))
In your case, using '...' helps you avoid the `-escaping that "..." requires to make PowerShell treat $ and ` (and ") verbatim, as shown above.
For a comprehensive overview of PowerShell's -replace operator, see this answer.

Escape string in PowerShell Regex to a regular string

I have a string that contains some regex in, $(=?, Now this string is a password that I need to pass for some application that I'm building.
The code that I'm trying to use is:
$x = 'GIWs#K?hks2v&HKXb$S9=HK*AZN=i!(S?7'
[Regex]::Escape($x)
I've already tried the method with [Regex]::Escape() and it doesn't meet my requirements because I'm trying to insert the string as a password and it replacing the Regex with \.
Perhaps after I'm doing the [Regex]::Escape() should I try to delete the \ that I'm getting from the result of the command?
After running the [Regex]::Escape() this is the result I'm getting when printing the output:
GIWs#K\?hks2v&HKXb=HK\*AZN=i!\(S\?7
I'm trying to achieve the string without the ' \ ' characters but with the Escape function:
GIWs#K?hks2v&HKXb=HK*AZN=i!(S?7
This is not an answer because I don't know what the problem actually is. However, there are some inherent problems with your current attempt to handle the password string. If you use double quotes ("") around a string, PowerShell will interpolate the string inside the quotes. So any alphanumeric characters following an unescaped $, will be considered a variable name during interpolation. If that variable has no value, $variable will be replaced with a null value. You can see this behavior below:
"rt4837s$GT=\"
rt4837s=\
You should use single quotes ('') when quoting string literals (characters that will be left as is). PowerShell will not attempt interpolation when unescaped single quote pairs are encountered unless there is quote nesting. See below:
'rt4837s$GT=\'
rt4837s$GT=\
If you need a regex escaped string, the same rules apply from above and you should use single quotes.
[regex]::escape('dfaseryh$S9=r??*')
dfaseryh\$S9=r\?\?\*
If for any reason, you need to access that string later without the escape characters, then you can use the regex method Unescape().
[regex]::unescape('dfaseryh\$S9=r\?\?\*')
dfaseryh$S9=r??*
Practical Example of Using Regex Replace:
$OriginalString = 'Username = Anonymous; Password = <password>'
$regexReplace = [regex]::Escape('<password>')
$Password = 'GIWs#K?hks2v&HKXb$S9=HK*AZN=i!(S?7'
$OriginalString -replace $regexReplace,($Password -replace '\$','$$$$')
# Output
Username = Anonymous; Password = GIWs#K?hks2v&HKXb$S9=HK*AZN=i!(S?7
In the code above, $OriginalString is just an ordinary string that can be retrieved from any command or set by a coder. It contains a string <password> that we want to replace with a complex password string GIWs#K?hks2v&HKXb$S9=HK*AZN=i!(S?7.
$Password contains the complex password. Since we only care about replacing <password> and are choosing to use regex replace operator -replace, we need a valid regex expression for matching <password>. There is a caveat here though. When using -replace, the $ in the replacement string is used to prefix capture group names. So there can be cases where the literal string has an unintentional replacement. Capture group 0 is always there if there is a match. So $0 will always cause issues without proper escaping. It is probably best to just escape $ regardless.
For the regex match, we use [regex]::Escape('<password>') since we are unsure if <> are special in regex. If there are no special characters, then the string within the regex expression will not be modified. If it does contain special characters, they will be escaped with \.
As a result, <password> is replaced with GIWs#K?hks2v&HKXb$S9=HK*AZN=i!(S?7.
A recap of the syntax is as follows:
'String With Something You Want to Replace' -replace 'Regex Expression to Match String You Want to Replace','Replacement That Is a Literal String With Escaped $'

How to locate a mismatched text delimiter

I'm trying to remove double quotes that appear within a string coming from a dB because it's causing an stream error in another application. I can't clean up the dB to remove these, so I need to replace the character on the fly.
I've tried using sed, ssed, and perl all without success. This regular expression is locating the problem quotes, but when I plug it into sed to replace them with a single quote my output still contains the double quote.
sed "s/(\?<\!\t|^)\"(\?\!\t|$)/'/g" test.txt
I'm on Mac, if this looks a bit odd.
The regex is valid, but when I test on a tab-delimited file containing this:
"foo" "rea"son" "text's"
My output is identical to the above. Any idea what I'm doing wrong?
Thanks
I assume you want to turn all occurrences of " that are not on a field boundary (i.e. either preceded or succeeded by either a tab or the beginning/end of the string) by '.
This can be done using perl and the following substitution:
s/(?<=[^\t])"(?=[^\t\n])/'/g;
(With sed this is not directly possible as it does not support look-behind / look-ahead assertions.)
To use this code on the command line, it needs to be escaped for whatever shell you're using. Assuming bash or a similar sh-like shell:
perl -pe 's/(?<=[^\t])"(?=[^\t\n])/'\''/g' test.txt
Here I use '...' to quote most of the code. To get a single ' into the quoted string, I leave the quoted area ...', add an escaped single quote \', and switch back into a single-quoted string '.... That's why a literal ' turns into '\'' on the command line.

Using regex to find a double quote within string encased in double quotes

I am using ultraedit with regex. I would like to find (and replace) and embedded double quotes found withing a string that starts/ends with a double quote. This is a text file with pipe | as the delimeter.
How do I find the embedded double quotes:
"This string is ok."|"This is example with a "C" double quoted grade in middle."|"Next line"
I eventually need to replace the double quotes in "C" to just have C.
The big trade off in CSV is correct parsing in every case versus simplicity.
This is a resonably moderated approach. If you have really wily strings with quotes next to pipes in them, you better use something like PERL and Text::CSV.
There is a bother with a regex that requires a non-pipe character on each side of the quote (such as [^|]) in that the parser will absorb the C and then won't find the other quote next to the C.
This example will work pretty well as long as you don't have pipes and quotes next to each other in your actual CSV strings. The lookaheads and behinds are zero-width, so they do not remove any additional characters besides the quote.
1 2 3 4
(?<!^)(?<!\|)"(?!\|)(?!$)
Don't match quotes at the beginning of the line.
Don't match quotes with a pipe in front.
Don't match quotes with a pipe afterwards.
Don't match quotes at the end of a string.
Every quote thus matched can be removed. Don't forget to specify global replacement to get all of the quotes.
Try this find:
(["][^"]*)["]C["]([^"]*["])
and replace:
\1C\2
Turn on Regular Expressions in Perl mode.
Screen shot of
UltraEdit Professional Text/HEX Editor
Version 21.30.0.1005
Trying it out.
Start with:
"This string is ok."|"This is example with a "C" double quoted grade in middle."|"Next line"
"This string is ok."|"This is example with a C double quoted grade in middle."|"Next line"
Ends with:
"This string is ok."|"This is example with a C double quoted grade in middle."|"Next line"
"This string is ok."|"This is example with a C double quoted grade in middle."|"Next line"
Breakdown of the regex FIND.
First part.
(["][^"]*)
from (["][^"]*)["]C["]([^"]*["])
This looks for a sequence of:
Double quote: ["].
Any number of characters that are not double quotes: [^"]*
The brackets that surround ["][^"]* indicate that the regex engine should store this sequence of characters so that the REPLACE part can refer back to it (as back references).
Note that this is repeated at the start and end - meaning that there are two sequences stored.
Second part.
["]C["]
from (["][^"]*)["]C["]([^"]*["])
This looks for a sequence of:
Double quote: ["].
The capital letter C (which may or may not stand for Cookies).
Double quote: ["].
Breakdown of the regex REPLACE.
\1C\2
\1 is a back reference that means replace this with the first sequence saved.
The capital letter C (which may or may not stand for Cookies).
\2 is a back reference that means replace this with the second sequence saved.
For the example you gave just "\w" works as the regex to find "C"
Try it here
The replacing mechanism is probably built into ultraedit
You really don't want to do this with regex. You should use a csv parser that can understand pipe delimiters. If I were to this with just regex, I would use multiple replacements like this:
Find and replace the good quotes with placeholder to text. Start/end quote:
s/(^"|"$)/QUOTE/g
Quotes near pipe delimiters:
s/"\|"/DELIMITER/g
Now only embedded double quotes remain. To delete all of them:
s/"//g
Now put the good quotes back:
s/QUOTE|DELIMITER/"/g
nanny posted a good solution, but for a Perl script, not for usage in a text editor like UltraEdit.
In general it is possible to have double quotes within a field value. But each double quote must be escaped with one more double quote. This is explained for example in Wikipedia article about comma-separated values.
This very simple escaping algorithm makes reading in a CSV file character by character coded in a programming language very easy. But double quotes, separators and line breaks included in a double quoted value are a nightmare for a regular expression find and replace in a CSV file.
I have recorded several replaces into an UltraEdit macro
InsertMode
ColumnModeOff
Top
PerlReOn
Find MatchCase RegExp "^"|"$"
Replace All "QuOtE"
Find MatchCase ""|"
Replace All "QuOtE|"
Find MatchCase "|""
Replace All "|QuOtE"
Find MatchCase """"
Replace All "QuOtEQuOtE"
Find MatchCase """
Replace All """"
Find MatchCase "QuOtE"
Replace All """
The first replace is a Perl regular expression replace. Each double quote at beginning or end of a line is replaced by the string QuOtE by this replace. I'm quite sure that QuOtE does not exist in the CSV file.
Each double quote before and after the pipe character is also replaced by QuOtE by the next 2 non regular expression replaces.
Escaped double quotes "" in the CSV file are replaced next by QuOtEQuOtE with a non regular expression replace.
Now the remaining single double quotes are replaced by two double quotes to make them valid in CSV file. You could of course also remove those single double quotes.
Finally, all QuOtE are replaced back to double quotes.
Note: This is not the ultimate solution. Those replaces could produce nevertheless a wrong result, for example for an already valid CSV line like this one
"first value with separator ""|"" included"|second value|"third value again with separator|"|fourth value contains ""Hello!"""|fifth value
as the result is
"first value with separator """|""" included"|second value|"third value again with separator|"|fourth value contains ""Hello!"""|fifth value
PS: The valid example line above should be displayed in a spreadsheet application as
first value with separator "|" included second value third value again with separator| fourth value contains "Hello!" fifth value

Escaping single quote in a sed command containing variables containing color escape codes?

I'm using sed to replace every instance of " is " by a colorized "'s ".
To do this, it surrounds the result by a color variable r and a blank variable x, which are interpreted literally. echo -e then makes the colors appear. Nothing new here.
The problem arises when I try to add the apostrophe (which is actually a single quote); I can't escape it without messing up the color escape code.
Here is my code without the apostrophe I'm trying to add:
r='\e[0;31m' # red
x='\e[0m' # reset color
sed 's/ is /\'${r}'s\'${x}'/g' # replace " is " by "'s "
I tried double quotes, multiple backslashes, but everything either broke the color code, or failed to escape the single quote. In the meantime, I'm using a true apostrophe ( ’ ), but it it's not the best solution, because it doesn't render properly in the TTY.
If you want to keep the single quotes, then you need '"'"'
The first quote ends the current single quoted string. Then we have "'" which expands to a single quote. \' would also work but doesn't look as good.
The last single quote starts the quoted string again.
An alternative in your case would be "s/ is /${r}'s${x}/g" (i.e. only use double quotes).
But then, you need to use r='\\e[0;31m' because the expansion in the string will string one level of escapes.