'export a string from poweshell 1 to powershell 2
I have a shell script file.
./1.ps1
./2.ps1
I generate a string such as env-0
in 1.ps1
and need to export it to 2.ps1
.
UPDATE:
1.ps1 generate many string and I couldn't pass my env-0 as argument to 2.ps1
.
Do you have another solution?
Solution 1:[1]
PowerShell's stream-like I/O model is a little unusual, but any value not captured is basically output - so to output the string env-0
from 1.ps1
, this is literally all you need:
"env-0"
Now that 1.ps1
outputs a string value, we need some way to feed it to 2.ps1
.
You can either rely on unbound positional arguments, which will automatically be available in the target script/function via the $args
variable:
# 2.ps1
$envString = $args[0]
# work with your `$envString` value here
To invoke:
$envString = ./1.ps1
./2.ps1 $envString
# or
./2.ps1 $(./1.ps1)
You can also accept pipeline input by consuming the $input
automatic input enumerator variable:
# 2.ps1
$input |ForEach-Object {
$envString = $_
# work with your `$envString` value here
}
To invoke:
./1.ps1 |./2.ps1
This might be useful if you intend to provide multiple inputs to 2.ps1
in succession:
# This will execute `./1.ps1` 100 times, but `./2.ps1` will only be executed once, and the output continuously fed to it as pipeline input
1..100 |ForEach-Object { ./1.ps1 } | ./2.ps1
Finally, if you want to write scripts for more advanced scenarios (multiple input parameters, input validation, argument completion etc.), you'll want to explicitly declare named parameter(s) with a param()
block:
# ./2.ps1
param(
[Parameter(Mandatory)]
[string]$Environment
)
# work with $Environment here
To invoke:
./2.ps1 -Environment $(./1.ps1)
It's worth noting that you can use the [Parameter()]
attribute to modify the binding behavior so you still get pipeline support:
# ./2.ps1
param(
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
[string]$Environment
)
# work with $Environment here
Now that we've added both the Position
and a ValueFromPipeline
flags, we can pass the string via the pipeline, by name, or positionally all at once:
# These all work now
./2.ps1 -Environment $(./1.ps1)
./2.ps1 $(./1.ps1)
./1.ps1 |./2.ps1
The only caveat is that you can't pipe multiple input values anymore - for that, you'll need to move the script body into a special process
block:
# ./2.ps1
param(
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
[string]$Environment
)
process {
# work with $Environment here
}
The process
block will execute exactly once for each pipeline input, so now piping multiple values works again ()along with the previous 3 examples:
1..100 |ForEach-Object { ./1.ps1 } | ./2.ps1
So that's my solution:
# 1.ps1
"env-0"
# 2.ps1
# ./2.ps1
param(
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
[string]$Environment
)
process {
# work with $Environment here
}
For more information about advanced parameters and their binding semantics and how to utilise them, see the about_Functions_Advanced_Parameters
help topic
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |