25yicms利用ASP.NET(C#)+MSSQL技术全力打造功能最强大的营销型企业网站管理系统,企业做网站系统,做网站软件,提供div+css企业网站模板。
阅读内容

C#调用BashShell来快速操作Linux


时间:2015/05/03   来源:企业网站管理系统
 一、C#直接调用BashShell所产生的问题
 
使用C#调其他应用,毫无疑问最直接的方法就是“System.Diagnostics”中的Process.Start了。但当我们使用Process.Start时,却发现连最简单的命令都无法调用,更无从谈起调用并接受返回了。
C#直接调用BashShell所产生的问题
上图为其中一种错误(当然还会有更多的问题出现,这里就不列举了)。
 
二、使用C的popen方式调用
正由于Process.Start无法直接调用BashShell的命令,我们需要绕道而行。
我们先看下C语言,C语言调用Shell的方式有多种,我们选择了popen函数的方式进行调用,先看一下以下的这个demo: 
#include<stdio.h>
int main(){
    FILE *fp;
    char buffer[255];
    fp=popen("ls /home/le","r");
    fread(buffer,255,255,fp);
    pclose(fp);
    printf("%s",buffer);
}
使用C的popen方式调用
通过poepn管道并完成输出重定向。
 
三、通过调用C来间接调用Shell
既然C已经可以实现对BashShell的调用已经管道重定向,那我们则可以再通过C#调用C的方式,进而间接的完成对BashShell的调用。
我们先对自己的C函数进行改造,改造后的代码如下(对具体操作有疑问的读者可参见《如何让C为C#提供函数》): 
#include<stdio.h>
#include<string.h>
void* ConvertToCStr(char* input,char* res,int *length){
    int i;
    for(i=0;i<*length;i++){
        res[i]=*(input+2*i);
    }
    res[i]='\0';
}
void* BashHelper(char* cmdStr,int* cmdLength,char* output,int* length){
    FILE* fp;
    char buffer[*length];
    char cmd[*cmdLength+1];
    ConvertToCStr(cmdStr,cmd,cmdLength);
    fp=popen(cmd,"r");
    fread(buffer,*length,*length,fp);
    pclose(fp);
    strcat(output,buffer);    
}
同样的我们也把C# Shell进行改造(没有Intellisense果然难写,我先在控制台写好再拷贝过来) 
 
#!/bin/env csharp
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
class Clib
{
    public static string InvokeBash(string cmdStr)
    {
        char[] output = new char[255];
        unsafe
        {
            fixed (char* c = cmdStr)
            fixed (char* op = output)
            {
                int cmdLenth = cmdStr.Length;
                int outputLength = output.Length;
                Clib.BashHelper(c, &cmdLenth, op, &outputLength);
                return Marshal.PtrToStringAnsi((IntPtr)op);
            }
        }
    }
 
    [DllImport("/你存放so的地址/shell.so", CallingConvention = CallingConvention.StdCall)]
    static unsafe extern void BashHelper(char* cmdStr, int* cmdLength, char* output, int* length);
}
var cmdStr = "/bin/ls /";
var output = Clib.InvokeBash(cmdStr);
Console.Write(output);
完成之后,我们再次在Shell中调用。
 通过调用C来间接调用Shell
成功执行BashShell命令并把返回输出重定向到C#中。
可能有读者会有这么一个疑问:“这跟直接写BashShell没啥差别啊?!”此言差矣,C#有C#的优势,Bash有Bash的优势,将两者结合起来后,可以形成互补,利用Bash可以快速的操作Linux,而一些Bash无法提供的功能,譬如写入数据库、调用某些服务的API、做其他BashShell无法做的事情等。 
+上一篇 没有了
+下一篇 对Spark Streaming默认的配置进行修改调优
点击次数:       打印此页  关闭