I have some strange situation in Powershell. When I run:
PS> node.exe [PATH_TO_GRUNT]\grunt
I got full output (30-40 lines), but when I run:
PS> Write-Host(node.exe [PATH_TO_GRUNT]\grunt)
I gives me only one line. What is wrong with this? I tried to add --no-color, 2>&1 options but they don't work at all.
Try with -Separator flag:
PS> Write-Host(node.exe [PATH_TO_GRUNT]\grunt) -Separator `n
Related
I am trying around the following highly used tools:
prettyjson
prettier
For example when I run the following on Powershell:
echo '{"a": 1}' | prettyjson
The terminal will just keep waiting for inputs till CTRL+C pressed and it exits with no expected output.
The workaround is to add .cmd to the command or just use cmd instead:
echo '{"a": 1}' | prettyjson.cmd
Outputs
a: 1
This seems to be a known limitation and a pull request is available:
https://github.com/npm/cmd-shim/pull/43
import os
os.system("powershell.exe [Get-ItemProperty
HKLM:\\Software\\Wow6432Node\\Microsoft\\\Windows\\CurrentVersion\\Uninstall\\*| Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table –AutoSize > D:\\application whitelisting\\InstalledProgramsPS.txt ]")
this is my code. I want to display the list of software installed in the system.
but i am getting error like
Select-Object is not recognized as an external or internal command.
when i execute the same command using powershell, it is working fine.
can anyone please help?
thanks in advance.
The reason is that Powershell's command parameter is not properly constructed. os.system() call will star a CMD session, and Select-Object is not recognized as an external or internal command is an error message from CMD.
Let's see what CMD does. First it will run Powershell and pass some arguments. Note the triple backslash, which is an error by itself and needs to be fixed.
powershell.exe [Get-ItemProperty HKLM:\\Software\\Wow6432Node\\Microsoft\\\Windows\\CurrentVersion\\Uninstall\\*
| Select-Object DisplayName, DisplayVersion, Publisher, InstallDate
Now, the first thing is that Powershell is invoked and (wrongly) paramerized Get-ItemProperty is passed. Because the pipe char | is used in CMD as well, it is interpreted as a command for CMD. Thus CMD tries to pipe the first command's output to Select-Object, but there isn't such a command in CMD. Thus the error.
To fix the issue, use -command "<commands>" to pass commands to Powershell. The double quotes " are used to create a single string that CMD passes to Powershell as an argument.
powershell.exe -command "Get-ItemProperty HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*| Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table -AutoSize > D:\\application whitelisting\\InstalledProgramsPS.txt"
I have a Jenkins console output that looks like this:
Started by remote host 10.16.17.13
Building remotely on ep9infrajen201 (ep9) in workspace d:\Jenkins\workspace\Tools\Provision
[AWS-NetProvision] $ powershell.exe -NonInteractive -ExecutionPolicy ByPass "& 'C:\Users\user\AppData\Local\Temp\jenkins12345.ps1'"
Request network range: 10.1.0.0/13
{
"networks": [
"10.1.0.0/24"
]
}
Finished: SUCCESS
I get this from a curl command that I run. to check the JENKINS_JOB_URL/lastBuild/consoleText
My question is, for the sake of some other automation I am doing, how do I get just "10.1.0.0/24" so I can assign it to a shell variable using LINUX tools?
Thank you
Since you listed jq among the tags of your duplicate question, I'll assume you have jq installed. You have to clean up your output to get JSON first, then get to the part of JSON you need. awk does the former, jq the latter.
.... | awk '/^{$/{p=1}{if(p){print}}/^}$/{p=0}' | jq -r .networks[0]
The AWK script looks for { on its own on a line to turn on a flag p; prints the current line if the flag is set; and switches off the flag when it encounters } all by itself.
EDIT: Since this output was generated on a DOS machine, it has DOS line endings (\r\n). To convert those before awk, additionally pipe through dos2unix.
I need to create ONE integrated script that sets some environment variables, downloads a file using wget and runs it.
The challenge is that it needs to be the SAME script that can run on both Windows PowerShell and also bash / shell.
This is the shell script:
#!/bin/bash
# download a script
wget http://www.example.org/my.script -O my.script
# set a couple of environment variables
export script_source=http://www.example.org
export some_value=floob
# now execute the downloaded script
bash ./my.script
This is the same thing in PowerShell:
wget http://www.example.org/my.script -O my.script.ps1
$env:script_source="http://www.example.org"
$env:some_value="floob"
PowerShell -File ./my.script.ps1
So I wonder if somehow these two scripts can be merged and run successfully on either platform?
I've been trying to find a way to put them in the same script and get bash and PowerShell.exe to ignore errors but have had no success doing so.
Any guesses?
It is possible; I don't know how compatible this is, but PowerShell treats strings as text and they end up on screen, Bash treats them as commands and tries to run them, and both support the same function definition syntax. So, put a function name in quotes and only Bash will run it, put "exit" in quotes and only Bash will exit. Then write PowerShell code after.
NB. this works because the syntax in both shells overlaps, and your script is simple - run commands and deal with variables. If you try to use more advanced script (if/then, for, switch, case, etc.) for either language, the other one will probably complain.
Save this as dual.ps1 so PowerShell is happy with it, chmod +x dual.ps1 so Bash will run it
#!/bin/bash
function DoBashThings {
wget http://www.example.org/my.script -O my.script
# set a couple of environment variables
export script_source=http://www.example.org
export some_value=floob
# now execute the downloaded script
bash ./my.script
}
"DoBashThings" # This runs the bash script, in PS it's just a string
"exit" # This quits the bash version, in PS it's just a string
# PowerShell code here
# --------------------
Invoke-WebRequest "http://www.example.org/my.script.ps1" -OutFile my.script.ps1
$env:script_source="http://www.example.org"
$env:some_value="floob"
PowerShell -File ./my.script.ps1
then
./dual.ps1
on either system.
Edit: You can include more complex code by commenting the code blocks with a distinct prefix, then having each language filter out its own code and eval it (usual security caveats apply with eval), e.g. with this approach (incorporating suggestion from Harry Johnston ):
#!/bin/bash
#posh $num = 200
#posh if (150 -lt $num) {
#posh write-host "PowerShell here"
#posh }
#bash thing="xyz"
#bash if [ "$thing" = "xyz" ]
#bash then
#bash echo "Bash here"
#bash fi
function RunBashStuff {
eval "$(grep '^#bash' $0 | sed -e 's/^#bash //')"
}
"RunBashStuff"
"exit"
((Get-Content $MyInvocation.MyCommand.Source) -match '^#posh' -replace '^#posh ') -join "`n" | Invoke-Expression
While the other answer is great (thank you TessellatingHeckler and Harry Johnston)
(and also thank you j-p-hutchins for fixing the error with true)
We can actually do way better
Work with more shells (e.g. work for Ubuntu's dash)
Less likely to break in future situations
No need to waste processing time re-reading/evaling the script
Waste less characters/lines on confusing syntax(we can get away with a mere 41 chars, and mere 3 lines)
Even Keep syntax highlighting functional
Copy Paste Code
Save this as your_thing.ps1 for it to run as powershell on Windows and run as shell on all other operating systems.
#!/usr/bin/env sh
echo --% >/dev/null;: ' | out-null
<#'
#
# sh part
#
echo "hello from bash/dash/zsh"
echo "do whatver you want just dont use #> directly"
echo "e.g. do #""> or something similar"
# end bash part
exit #>
#
# powershell part
#
echo "hello from powershell"
echo "you literally don't have to escape anything here"
How? (its actually simple)
We want to start a multi-line comment in powershell without causing an error in bash/shell.
Powershell has multi-line comments <# but as-is they would cause problems in bash/shell languages. We need to use a string like "<#" for bash, but we need it to NOT be a string in powershell.
Powershell has a stop-parsing arg --% lets write single quote without starting a string, e.g. echo --% ' blah ' will print out ' blah '. This is great because in shell/bash the single quotes do start a string, e.g. echo --% ' blah ' will print out blah
We need a command in order to use powershell's stop-parsing-args, lucky for us both powershell and bash have an echo command
So, in bash we can echo a string with <#, but powershell the same code finishes the echo command then starts a multi-line comment
Finally we add >/dev/null to bash so that it doesn't print out --% every time, and we add | out-null so that powershell doesn't print out >/dev/null;: ' every time.
The syntax highlighting tells the story more visually
Powershell Highlighting
All the green stuff is ignored by powershell (comments)
The gray --% is special
The | out-null is special
The white parts are just string-arguments without quotes
(even the single quote is equivlent to "'")
The <# is the start of a multi-line comment
Bash Highlighting
For bash its totally different.
Lime green + underline are the commands.
The --% isn't special, its just an argument
But the ; is special
The purple is output-redirection
Then : is just the standard "do nothing" shell command
Then the ' starts a string argument that ends on the next line
Caveats?
Almost almost none. Powershell legitimately has no downside. The Bash caveats are easy to fix, and are exceedingly rare
If you need #> in a bash string, you'll need to escape it somehow.
changing "#>" to "#"">"or from ' blah #> ' to ' blah #''> '.
If you have a comment #> and for some reason you CANNOT change that comment (this is what I mean by exceedingly rare), you can actually just use #>, you just have to add re-add those first two lines (eg true --% etc) right after your #> comment
One even more exceedingly rare case is where you are using the # to remove parts of a string (I bet most don't even know this is a bash feature). Example code below
https://man7.org/linux/man-pages/man1/bash.1.html#EXPANSION
var1=">blah"
echo ${var1#>}
# ^ removes the > from var1
To fix this one, well there are alternative ways of removeing chars from the begining of a string, use them instead.
Following up on Jeff Hykin's answer, I have found that the first line, while it is happy in bash, produces this output in PowerShell. Note that it is still fully functional, just noisy.
true : The term 'true' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling
of the name, or if a path was included, verify that the path is correct and try again.
At C:\Users\jp\scratch\envar.ps1:4 char:1
+ true --% ; : '
+ ~~~~
+ CategoryInfo : ObjectNotFound: (true:String) [], CommandNotFoundException
hello from powershell
I am experimenting with changing the first lines from:
true --% ; : '
<#'
to:
echo --% > /dev/null ; : ' | out-null
<#'
In very limited testing this seems to be working in bash and powershell. For reference, I am "sourcing" the scripts not "calling" them, e.g. . env.ps1 in bash and . ./env.ps1 in powershell.
I am trying to make logstash installation work by simply executing the command given in the documentation to echo back what ever typed.But that gives me the following error.
My command
C:\logstash-1.4.0\bin>logstash.bat agent -e 'input{stdin{}}output{stdout{}}'
And the error
Error: Expected one of #, input, filter, output at line 1, column 1 (byte 1) aft
er
You may be interested in the '--configtest' flag which you can
use to validate logstash's configuration before you choose
to restart a running system."
Please help.Thanks in advance!
I am testing with logstash-1.4.0 on linux with this tutorial.
I think it is possible a bug on this version.
For example, I test this command on both linux and window. Everything is ok on linux. But it will occur your error at window!!
bin>logstash agent -e 'input{stdin{}}output{stdout{}}'
For my recommendation, you can write your configuration in a file. For example, save input{stdin{}}output{stdout{}} to a file call "stdin.conf". Then when you start logstash, don't use -e flag, instead use -f and specific your configuration file.
bin>logstash agent -f stdin.conf
Hope this can help you.
Try without quotes
C:\logstash-1.4.0\bin>logstash.bat agent -e input{stdin{}}output{stdout{}}
I get this error when I run -e with --debug. I have to remove -e. Example:
GEM_HOME="/opt/logstash/vendor/bundle/jruby/1.9/" /usr/lib/jvm/java-1.6.0/bin/java -server -Xms765M -Xmx2297M -Djava.io.tmpdir=/opt/logstash/forwarder/tmp/ -Xmx2297M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -Djava.awt.headless=true -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -jar /opt/logstash/forwarder/vendor/jar/jruby-complete-1.7.11.jar -I/opt/logstash/forwarder/lib /opt/logstash/forwarder/lib/logstash/runner.rb agent -f /opt/logstash/forwarder/etc/conf.d/ -l /opt/logstash/forwarder/log/logstash.log -w 1 --debug