我正在尝试编写一个带有数组参数的Powershell函数.我想用数组作为参数或管道输入来调用它.所以,调用看起来像这样:
my-function -arg 1,2,3,4
my-function 1,2,3,4
1,2,3,4 | my-function
Run Code Online (Sandbox Code Playgroud)
获得前两个很容易:
function my-function {
param([string[]]$arg)
$arg
}
Run Code Online (Sandbox Code Playgroud)
但是,对于管道输入,它更难.通过使用ValueFromPipeline,很容易在进程块中一次获取一个参数,但这意味着$ args变量是带有管道输入的单个值,但是如果使用-args则是一个数组.我可以在END块中使用$ input,但这根本不会得到-args输入,并且在END块中使用$ args只能从管道中获取最终项目.
我想我可以通过使用begin/process/end blocks从管道中显式收集参数值来完成此操作,如下所示:
function my-function {
param([Parameter(ValueFromPipeline=$true)][string[]]$args)
begin {
$a = @()
}
process {
$a += $args
}
end {
# Process array here
$a -join ':'
}
}
Run Code Online (Sandbox Code Playgroud)
但这似乎非常混乱.对我来说这似乎也是一个相对常见的要求,所以我希望它易于实现.我错过了一种更简单的方法吗?或者如果没有,有没有办法将参数处理封装到子函数中,这样我就不必在我想要工作的每个函数中包含所有这些?
我的具体要求是我正在编写以SQL命令为输入的脚本.因为SQL可能是冗长的,所以我想允许在命令中管道(可能由另一个命令生成,或者从文件的get-contents生成),但也允许使用参数形式,以获得快速的SELECT语句.所以我从管道中获取了一系列字符串,或者作为参数.如果我得到一个数组,我只想用"n"加入它来制作一个字符串 - 逐行处理是不合适的.
我想另一个问题是,是否有一个更好的设计我的脚本,使得像这样更干净的多行输入?
谢谢 - 诀窍是不要使用ValueFromPipeline然后......
我在按照我想要的方式工作时遇到这么多麻烦的原因是在我的测试脚本中,我使用$ args作为我的参数变量的名称,忘记它是一个自动变量.所以事情很奇怪......
PS> 1,2,3,4 | ./args
PS> get-content args.ps1
param([string[]]$args)
if ($null -eq $args) { $args = @($input) }
$args -join ':'
Run Code Online (Sandbox Code Playgroud)
Doh …
我正在使用mingw gcc和msys来构建一些GNU实用程序.在过去,我遇到了很多由需要不同版本的libiconv的不同可执行文件引起的问题,所以为了避免这个问题,我想将iconv静态链接到可执行文件中.
我使用mingw和msys with configure --enable-static构建了libiconv.这将创建DLL,.dll.a导入库和普通的.a静态库.
但是,当我尝试构建另一个与简单的-liconv链接的程序时,我得到了链接的DLL.我假设ld由于某种原因更喜欢导入库而不是静态库(通常不是一个糟糕的选择,这是一个特例).
如何确保我构建的程序是静态链接的?一个显而易见的方法是在执行构建时删除.dll.a文件.这可能是最简单的选择,但我很好奇 - 是否有一个链接器标志我可以设置(通过像LDFLAGS之类的东西)来强制iconv被静态加载(理想情况下,不会影响其他库,但是在紧要关头我会没事的静态加载所有库)
我正在用Python编写一个小型的作业调度程序.调度程序可以被赋予一系列callables和依赖项,并且应该运行callables,确保在任何前任之前没有任务运行.
我试图遵循测试驱动的方法,我遇到了测试依赖项处理的问题.我的测试代码如下所示:
def test_add_dependency(self):
"""Tasks can be added with dependencies"""
# TODO: Unreliable test, may work sometimes because by default, task
# running order is indeterminate.
self.done = []
def test(id):
self.done.append("Test " + id)
s = Schedule()
tA = Task("Test A", partial(test, "A"))
tB = Task("Test B", partial(test, "B"))
s.add_task(tA)
s.add_task(tB)
s.add_dependency(tA, tB)
s.run()
self.assertEqual(self.done, ["Test B", "Test A"])
Run Code Online (Sandbox Code Playgroud)
问题是这个测试(有时)甚至在我添加依赖项处理代码之前就已经有效了.这是因为规范没有说明必须以特定顺序运行任务.因此,即使忽略依赖性信息,正确的顺序也是完全有效的选择.
有没有办法编写测试来避免这种"偶然"的成功?在我看来,这是一种相当常见的情况,特别是在采用测试驱动的"不编写没有测试失败的代码"的方法时.
我想在我的Ubuntu服务器系统上安装Mercurial,但我不想要X(这是一个纯粹的控制台系统,根本没有GUI).如果我使用apt-get install mercurial所有X库都被拉入.我知道我可以忽略它们但我想保持我的系统最小化 - 有没有一种安装方式hg 没有任何GUI工具?
我有一个用Python编写的本机程序,期望它在stdin上输入.举个简单的例子,
#!python3
import sys
with open('foo.txt', encoding='utf8') as f:
f.write(sys.stdin.read())
Run Code Online (Sandbox Code Playgroud)
我希望能够将(PowerShell)字符串作为标准输入传递给此程序.Python期望其指定的编码中的标准输入$env:PYTHONIOENCODING,我通常会设置为UTF8(因此我不会得到任何编码错误).
但无论我做什么,角色都会被破坏.我在网上搜索并找到了改变[Console]::InputEncoding/ [Console]::OutputEncoding或使用的建议chcp,但似乎没有任何效果.
这是我的基本测试:
PS >[Console]::OutputEncoding.EncodingName
Unicode (UTF-8)
PS >[Console]::InputEncoding.EncodingName
Unicode (UTF-8)
PS >$env:PYTHONIOENCODING
utf-8
PS >python -c "print('\N{Euro sign}')" | python -c "import sys; print(sys.stdin.read())"
´???
PS >chcp 1252
Active code page: 1252
PS >python -c "print('\N{Euro sign}')" | python -c "import sys; print(sys.stdin.read())"
?
PS >chcp 65001
Active code page: 65001
PS >python -c "print('\N{Euro sign}')" | python -c …Run Code Online (Sandbox Code Playgroud) 我有高级功能
function Start-Executable {
[CmdletBinding()]
Param (
[String]$Arg1,
[String[]]$Arg2,
[Parameter(ValueFromPipeline=$true)][String[]]$PipeValue
)
Begin {
# Setup code
}
Process {
# What goes on here?
foreach ($val in $PipeValue) {
# Process val here
}
}
End {
}
}
Run Code Online (Sandbox Code Playgroud)
在我的设置代码中,我需要根据用户是否提供管道输入来做一些不同的事情。但是我不知道如何在 BEGIN 块中判断是否有管道输入。有什么我可以检查的吗?
我尝试的另一件事是在循环之前将设置代码放在 PROCESS 块中,$PipeValue但这不起作用,因为似乎为每个管道值调用一次 PROCESS 块,每次$PipeValue都是一个项目的数组. 那正确吗?如果为每个值重复调用 PROCESS,为什么我需要在 PROCESS 块内进行另一个循环?
更新
澄清一下,我想要做的是在 BEGIN 中创建一个进程,在 PROCESS 中输入它并在 END 中读取输出。为此,我需要设置RedirectStandardInput为$true是否有管道输入,否则不设置。
作为变通方法,我可以让用户指定一个额外的参数(如果他们弄错了,事情就不起作用),或者我可以$first_time在 BEGIN 中设置一个标志,然后在第一次调用 PROCESS 时创建进程。如果我在没有创建进程的情况下到达 END,我会在那里创建它RedirectStandardInputas $false …
我正在用C#编写虚拟机的实现,我需要实现VM的堆栈,它可以包含两种类型的条目 - 返回条目或回溯条目.实现这个的最佳方法是什么?
我目前正在使用基类型,如下所示:
class StackEntry { }
class Return : StackEntry { uint pc; }
class Backtrack : StackEntry { uint pc; object backtrack; }
Stack<StackEntry> stack;
Run Code Online (Sandbox Code Playgroud)
这样工作正常,但最终的类型测试和向下转换感觉很笨拙.
有没有更好的方法来处理这种类型的建筑?
我想编写一个过程,该过程在从并发程序运行时将输出记录到 Oracle 并发管理器日志,但在“独立”运行时写入 dbms_output。
PL/SQL 有没有办法检查我的代码是否正在从并发请求运行?我能找到的最好的方法是
select * from fnd_concurrent_requests
where oracle_session_id = userenv('SESSIONID');
Run Code Online (Sandbox Code Playgroud)
但这是相当慢的。是否有可以查询的函数或表可以更有效地为我提供信息?
我经常使用一些sed/perl/etc"one-liner"命令:
head -1 (打印文件的第一行)sed $d (删除文件的最后一行)perl -pe '$_ = qq($. $_)' (文件中的数字行)你明白了.
所有这些命令都具有相同的行为 - 它们可以从标准输入获取输入,或者处理名称作为参数传递的一系列文件.我想将这些常见脚本包装为Powershell函数,这样我就不必记住要使用的确切语法.但是,别名不能像那样工作,如果我用函数做"明显"的方法:
function numlines {
perl -pe '$_ = qq($. $_)' $args
}
Run Code Online (Sandbox Code Playgroud)
它使用文件作为arguments(numlines my_file.pl),但不使用pipe(cat my_file.pl | numlines)的输入.
有没有办法编写函数,以便它可以双向工作?
澄清 - 我可以使用bat文件来执行此操作.例如,numlines.bat包含
@perl -pe "$_ = qq($. $_)" %*
Run Code Online (Sandbox Code Playgroud)
但是当你按下CTRL-C时,不得不调用cmd.exe和bat文件的一般丑陋("终止批处理作业(Y/N)?"提示),这让我希望在Powershell中有一个类似的简单解决方案. .
根据理查德的建议,我试过:
function test {
[CmdletBinding()]
param(
[Parameter(mandatory=$true, ValueFromPipeline=$true)]
$data
)
process {
perl -pe '$_ = qq($. $_)'
}
}
Run Code Online (Sandbox Code Playgroud)
如果我那么做test file.txt(我想要有效地运行perl -pe '$_ = qq($. …