从.net core Linux调用shell命令时出现问题
我在从Linux.net核心控制台应用程序调用命令时遇到一些问题从.net core Linux调用shell命令时出现问题,linux,debian,.net-core,Linux,Debian,.net Core,我在从Linux.net核心控制台应用程序调用命令时遇到一些问题 Sub Main() Dim PI As New ProcessStartInfo Using Proc As New Process With PI .FileName = "cat" .Arguments = "/etc/*-release" .RedirectStandardOutput = True
Sub Main()
Dim PI As New ProcessStartInfo
Using Proc As New Process
With PI
.FileName = "cat"
.Arguments = "/etc/*-release"
.RedirectStandardOutput = True
.UseShellExecute = False
.CreateNoWindow = True
End With
Proc.StartInfo = PI
Proc.Start()
PI = Nothing
Console.Write(Proc.StandardOutput.ReadToEnd)
End Using
End Sub
我得到这个错误:
cat: '/etc/*-release': No such file or directory
如果我禁用重定向并将UseShellExecute设置为True,它就可以工作,但我希望能够在代码中使用输出。当您运行以下命令时
cat /etc/*-release
LinuxShell(可能是bash)计算每个参数,然后使用计算的参数调用程序。简单的单词本身计算,但变量(如$SOME_ARGUMENT
)和模式(如*
)计算值和文件名。因此,shell将上述内容计算为(假设只有一个文件):
因此,cat
程序只得到一个参数,没有任何像*
这样的glob
如果要在程序中模拟该行为,需要将UseShellExecute
设置为True
或者,也许你可以自己做评估。类似于Directory.EnumerateFiles
的API允许您执行以下操作:
Dim textFiles = Directory.EnumerateFiles("/etc/", "*-release")
然后,您需要遍历此集合,并使用确切的文件名作为.Arguments
值
编辑:但更进一步一点,你为什么还要这么做?如果您已经完全阅读了文件,为什么要调用cat
。为什么不直接调用Console.WriteLine()
文件本身,而不是调用cat
?Ahhh…明白了
我只需要使用bash-c“cat”“/etc/*-release”“
如果您想避免使用shell,那么您必须复制shell在扩展
/etc/*-release
时所做的工作。不太熟悉这种语言,但它可能有一个Unix Cglob()
函数的包装器或等价物?我没有仔细考虑到底发生了什么。我只是希望‘cat’可以执行“文件搜索”,而不是shell……但我现在明白了逻辑,谢谢。我正在制作一个管理工具,它将调用许多不同的命令,并且我制作了一个函数,每当我想启动一个命令CallCMD(EXE作为字符串,Args作为字符串())作为字符串时调用它。需要将输出保存为字符串,以便进一步处理。这似乎不可能将UseShellExecute
设置为True
cat/etc/*-release
只是一个例子……我希望它支持我在bash shell中使用的任何命令。不确定这些引用的真正含义,但它们看起来很古怪。传递给-c
的字符串应该是cat/etc/*-release
,不带任何额外的内部引号。例如,在Python中,这将是子流程调用(['bash','-c',cat/etc/*-release'])
,如果这有助于理解我想说的话。
Dim textFiles = Directory.EnumerateFiles("/etc/", "*-release")
Sub Main()
Dim PI As New ProcessStartInfo
Using Proc As New Process
With PI
.FileName = "bash"
.Arguments = "-c ""cat ""/etc/*-release"""""
.RedirectStandardOutput = True
.UseShellExecute = False
.CreateNoWindow = True
End With
Proc.StartInfo = PI
Proc.Start()
PI = Nothing
Console.Write(Proc.StandardOutput.ReadToEnd)
End Using
End Sub