How do i do the equivalent of this bash style command invocation in powershell 1.0
output = `VAR1=value /path/someCommand`
In essence i need to manufacture a private & temporary $env:VAR1 for the purpose of invoking someCommand.
You can set a process environment variable in PowerShell like so:
$env:VAR1 = 'value'
Then invoke the command:
/path/someCommand
Then remove the process env var:
remove-item Env:\Var1
Assuming you want to store the output of that command in var1:
$var1 = $_ | /path/someCommand
Assuming you want an alias so output will run that code whenever called:
Set-Alias output "$var = /path/someCommand"
Related
How does one send an echo y pipe to plink when starting them from [Diagnostics.Process]::Start
$meProcessID = ([Diagnostics.Process]::Start("echo y | plink.exe", "$($hostName) -l $($uPwd.GetNetworkCredential().Username) -pw $($uPwd.GetNetworkCredential().Password) \`"echo '$($uPwd.GetNetworkCredential().Password)' | sudo -S '/home/someuser/somescript.sh'\`"")).Id
Though there is this it doesn't really answer my question since it's asking about calling bash from powershell and mine is really about passing a value to a Window command from standard output to bypass a Host-Read type of prompt.
Ansgar Wiechers' helpful answer contains an effective solution and sensible security warnings.
Using a System.Diagnostics.Process instance with .RedirectStandardInput = $true, and use of .StandardInput to provide standard input after the process has started, gives you more flexibility, yet in your case the only modification that was needed was to pass your command line as an argument (2nd parameter), via option -c, to program cmd.exe (1st parameter).
[Diagnostics.Process]::Start()'s first parameter is only the executable name / path, not a full command line.
It is the 2nd parameter that accepts a string containing the arguments to pass to the executable.
Since you're using shell features, namely connecting multiple commands with a pipeline, you must use cmd.exe as the executable, and pass your pipeline as an argument to cmd.exe's /c option.
You could use powershell.exe too, but in this simple case it is sufficient - and faster - to use cmd.exe.
Here's a simplified example:
$meProcessID = ([Diagnostics.Process]::Start(
# Program to launch
'cmd',
# Arguments to pass
'/c echo 42 | powershell -nop -c "''stdin input: '' + $Input" & pause'
).Id
The above demonstrates that stdin input 42 is seen by the powershell process as such ($Input); it opens a new console window that shows the following:
stdin input: 42
Press any key to continue . . .
Redirect STDIN of the receiving process. Something like this:
$username = $uPwd.GetNetworkCredential().Username
$password = $uPwd.GetNetworkCredential().Password
$p = New-Object Diagnostics.Process
$p.StartInfo.FileName = 'plink.exe'
$p.StartInfo.Arguments = $hostName, '-l', $username, '-pw', $password,
"`"echo '${password}' | sudo -S '/home/someuser/somescript.sh'\`""
$p.StartInfo.RedirectStandardInput = $true
$p.StartInfo.UseShellExecute = $false
$p.Start()
$p.StandardInput.WriteLine('y')
$p.Id # get the PID
With that said, I assume that the echo y is for accepting the host key. Doing that effectively disables an important SSH security mechanism to counter Man-in-the-Middle attacks, so I strongly recommend against doing this. It's better to verify the SSH host key of the remote host and import it into the registry before doing automated connections. You could prepare a .reg file with the hash and import that wherever needed. You may also want to use public key authentication instead of password authentication.
You have been warned.
I have a problem with an execution of a shell script into a remote shell.
I can't get value of $ARQ_END.
ssh -T user#MACHINE << 'EOSSH'
/app/work/leo/ReturnFileName.sh #This script returns a filename like: ADDRESS_BR_RECIFE_20170913.txt
ARQ_END="`/app/work/leo/ReturnFileName.sh`"
EOSSH
echo $ARQ_END #Returns nothing! Expected to return: ADDRESS_BR_RECIFE_20170913.txt
Setting a variable in a subshell isn't visible in the parent shell. You need to set the variable directly in the parent shell. The way to do that is to pass the output of ReturnFileName.sh up through the ssh session and to the parent shell and capture it there.
ARQ_END=$(ssh user#MACHINE /app/work/leo/ReturnFileName.sh)
echo "$ARQ_END"
Thanks, it works!
I used the case as you posted:
ARQ_END=$(ssh user#MACHINE /app/work/leo/ReturnFileName.sh)
echo "$ARQ_END"
In OSX, I open a bash terminal and enter a PowerShell console.
In my PowerShell script, I would like to open another PowerShell console and execute a PowerShell script there.
Under Windows, I would do
Invoke-Expression ('cmd /c start powershell -Command test.ps1')
How could I do the samething in OSX?
To start a PowerShell instance in a new terminal window on macOS:
Without being able to pass arguments to it:
PS> open -a Terminal $PSHOME/powershell
If you want to run a given command:
Unfortunately, quite a bit more work is needed if you want to pass a command to run in the new PowerShell instance:
In essence, you need to place your command in a temporary, self-deleting, executable shell script that is invoked via a shebang line:
Note: Be sure to run at least PowerShell Core v6.0.0-beta.6 for this to work.
Function Start-InNewWindowMacOS {
param(
[Parameter(Mandatory)] [ScriptBlock] $ScriptBlock,
[Switch] $NoProfile,
[Switch] $NoExit
)
# Construct the shebang line
$shebangLine = '#!/usr/bin/env powershell'
# Add options, if specified:
# As an aside: Fundamentally, this wouldn't work on Linux, where
# the shebang line only supports *1* argument, which is `powershell` in this case.
if ($NoExit) { $shebangLine += ' -NoExit' }
if ($NoProfile) { $shebangLine += ' -NoProfile' }
# Create a temporary script file
$tmpScript = New-TemporaryFile
# Add the shebang line, the self-deletion code, and the script-block code.
# Note:
# * The self-deletion code assumes that the script was read *as a whole*
# on execution, which assumes that it is reasonably small.
# Ideally, the self-deletion code would use
# 'Remove-Item -LiteralPath $PSCommandPath`, but,
# as of PowerShell Core v6.0.0-beta.6, this doesn't work due to a bug
# - see https://github.com/PowerShell/PowerShell/issues/4217
# * UTF8 encoding is desired, but -Encoding utf8, regrettably, creates
# a file with BOM. For now, use ASCII.
# Once v6 is released, BOM-less UTF8 will be the *default*, in which
# case you'll be able to use `> $tmpScript` instead.
$shebangLine, "Remove-Item -LiteralPath '$tmpScript'", $ScriptBlock.ToString() |
Set-Content -Encoding Ascii -LiteralPath $tmpScript
# Make the script file executable.
chmod +x $tmpScript
# Invoke it in a new terminal window via `open -a Terminal`
# Note that `open` is a macOS-specific utility.
open -a Terminal -- $tmpScript
}
With this function defined, you can invoke PowerShell with a given command - specified as a script block - as follows:
# Sample invocation
Start-InNewWindowMacOS -NoExit { Get-Date }
I don't know anything about powershell on mac, if that even exists but to open a gui application like a terminal on Mac OS X you can use the open command:
open -a /Applications/Utilities/Terminal.app "" would be a new blank window
open -a /Applications/Utilities/Terminal.app somescrip.sh would be to run a script
or you can make an apple script and run that
save the following in a file (~/OpenNewTerminal.scp):
tell application "Terminal"
do script " "
activate
end tell
then you can run it with osascript
osascript ~/OpenNewTerminal.scp
of course the more bash idiomatic way would be to run in a subshell or in the background
subshell:
output=$(ls)
echo $output
background:
./command &
background with redirected output so it doesn't bleed into your current shell:
./command 2>&1 > /dev/null
I have installed the EnvInject plugin of Jenkins.
I add it in the properties content (In script content also doesn't work: echo's nothing)
I able to set environment variable e.g.:
TEST="hello world"
In shell:
echo ${TEST}
Output: Hello World
But when I try to put the output of a command in my variable it doesn't work:
HOSTNAME=`hostname`
In Shell
echo ${HOSTNAME}
Output: `hostname`
While when I set the environment variable in my shell (without the plugin it works):
In Shell
HOSTNAME=`hostname`
echo ${HOSTNAME}
Output: localhost
From job configuration you should use Inject environment variables to the build process / Evaluated Groovy script.
Depending on the configuration you could execute command and save it in map containing environment variables:
return [HOSTNAME: 'hostname'.execute().text]
or run Groovy equivalent:
return [HOSTNAME: java.net.InetAddress.getLocalHost().getHostName()]
I'm trying to get the current shell command (not $history[1] !), specifically i'd like to be able to replace the fish_title - (pwd), with specific running programs i.e. python if I'm in interactive shell, vim etc.
From the documentation:
The first argument to fish_title will contain the most recently executed foreground command as a string, starting with fish 2.2.
So a simple
function fish_title
echo $argv (set -q SSH_CONNECTION; and hostname)":" $PWD
end
should work.
From the documentation, Special Variables
_, the name of the currently running command.
The default fish_title function does this already, does it not?
function fish_title
echo $_ " "
set -q SSH_CONNECTION; and echo (hostname)":"
pwd
end