Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A .NET library that makes shelling out commands super easy and fluent.

License

NotificationsYou must be signed in to change notification settings

twitchax/Sheller

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Actions StatuscodecovGitHub ReleaseNuGet VersionNuGet Downloads

A .NET library that makes shelling out commands super easy and fluent. Think of it as a way to build human-readable shell scripts with the power of a full programming language.

Information

Install

dotnet add package Sheller

Test

Download the source and run.

dotnettest --filter os~nix

Or.

dotnettest --filter os~win

NOTE: Windows tests require WSL.

Compatibility

Latest .NET Standard 2.0.

Examples

This library is extendable, but you can run it a few ways depending on how you have extended it. For more examples, check out thetests.

Just as one would expect fromIEnumerable, and other fluent interface designs, the result of every call onIShell andIExecutable is anew instance. This means that you can reuse useful statements.

In addition,future calls will not affect any previous instances, meaning you can safely chain them without affecting the calling instance. A good example of this behavior is the fact thatmyEnumerable.Where(...) does not affectmyEnumerable.

In generalWith methods can be called multiple times (multiple entries are allowed per execution context) andUse methods can only be called once (only one entry is allowed per execution context). The context changes fromIShell toIExecutable upon callingIShell.UseExecutable, so the methods available will be different once that method is called.

Basic

With no extensions, you would run a command like this.

varechoResult=awaitSheller.Builder.UseShell("/bin/bash").WithEnvironmentVariable("MY_VAR","lol").UseExecutable("echo").WithArgument("$MY_VAR").ExecuteAsync();varexitCode=result.ExitCode;// 0varstandardOutput=result.StandardOutput;// "lol\n"varstandardError=result.StandardError;// ""varstartTime=result.StartTime;varendTime=result.EndTime;varrunTime=result.RunTime;

However, you can build your own customIShell andIExecutable implementations that yield code that looks like this (Sheller ships withBash andEcho by default).

varresult=awaitSheller.Builder.UseShell<Bash>().WithEnvironmentVariable("MY_VAR",varValue).UseExecutable<Echo>().WithArgument("$MY_VAR").ExecuteAsync();varechoValue=result;// "lol"

Reusable Objects

Just like one would expect fromIEnumerable, and other fluent designs, the result of every call onIShell andIExecutable is anew instance. This means that you can reuse useful statements.

In addition,future calls will not affect any previous instances, meaning you can safely chain them without affecting the calling instance. A good example of this behavior is the fact thatmyEnumerable.Where(...) does not affectmyEnumerable.

varshell=Builder.UseShell<Bash>().WithEnvironmentVariable("MY_VAR","cool");varanotherShell1=shell.WithEnvironmentVariable("MY_VAR_2","beans");varanotherShell2=shell.WithEnvironmentVariable("MY_VAR_2","stuff");varechoResult1=anotherShell1.UseExecutable<Echo>().WithArgument("$MY_VAR$MY_VAR_2").ExecuteAsync();//result: "coolbeans".varechoResult2=anotherShell1.UseExecutable<Echo>().WithArgument("$MY_VAR$MY_VAR_2").ExecuteAsync();//result: "coolstuff".

Environment Variables

You can set environment variables on the shell.

varresult=awaitBuilder.UseShell<Bash>().WithEnvironmentVariable("MY_VAR",expected).UseExecutable<Echo>().WithArgument("$MY_VAR").ExecuteAsync();

Standard Output/Error

You can capture standard output and standard error. These methods can be called multiple times.

awaitBuilder.UseShell<Bash>().UseExecutable<Echo>().WithArgument("saythings").WithStandardOutputHandler(Console.WriteLine).WithStandardErrorHandler().ExecuteAsync();

Standard Input

You can pass standard input that gets captured during execution. This method may be called multiple times.

varechoResult=awaitBuilder.UseShell<Bash>().UseExecutable("read var1; read var2; echo $var1$var2").WithStandardInput("cool").WithStandardInput("library").ExecuteAsync();// echoResult is "coollibrary".

Input Request Handler

You can provide a handler that will be called when execution is blocked and waiting for input. This can only be set once per execution context.

varechoResult=awaitBuilder.UseShell<Bash>().UseExecutable($"read var1; echo $var1").UseInputRequestHandler((stdout,stderr)=>{// Process stdout or stderr, if needed.// Process is blocked, waiting for this input.returnTask.FromResult("awesome");}).ExecuteAsync();// echoResult is "awesome".

No Throw

You can instruct the execution tonot throw on a non-zero exit code. This method may only be called once.

awaitBuilder.UseShell<Bash>().UseExecutable("foo").UseNoThrow().ExecuteAsync();

Result Selector

You can pass a map function toExecuteAsync to "select" the result.

varechoErrorCode=awaitBuilder.UseShell<Bash>().UseExecutable<Echo>().WithArgument("dummy").ExecuteAsync(cr=>{returncr.ExitCode;});// echoErrorCode is 0.

Execution Timeout

You can set the execution timeout. This method can only be called once.

awaitBuilder.UseShell<Bash>().UseExecutable<Sleep>().WithArgument("10").UseTimeout(TimeSpan.FromSeconds(5)).ExecuteAsync();

Post Execution Wait

You can provide waiters that process the result and wait upon a task before completion of the outer task. These waiters may be applied multiple times. You can also set a wait timeout (only one) withUseWaitTimeout.

varechoValue=awaitBuilder.UseShell<Bash>().UseExecutable<Echo>().WithArgument("dummy").WithWait(async cr=>{returnSomethingThatIsATask();}).UseWaitTimeout(TimeSpan.FromSeconds(30)).ExecuteAsync();

Reactive

You can subscribe to an internalIObservable. You can call the subscriber multiple times.

varevents=newList<string>();varcommand1=Builder.UseShell<Bash>().UseExecutable("echo").WithArgument(expected).WithSubscribe(o=>{o.Where(ev=>ev.Type==CommandEventType.StandardOutput).Select(ev=>ev.Data).Do(data=>{events.Add(data);}).Subscribe();}).ExecuteAsync();

Cancellation

You can set cancellation tokens. This method may be called multiple times.

using(varctSource=newCancellationTokenSource()){ctSource.CancelAfter(TimeSpan.FromSeconds(5));Builder.UseShell<Bash>().UseExecutable<Sleep>().WithArgument("10").WithCancellationToken(ctSource.Token).ExecuteAsync();}

Character Encoding

You can set the output character encoding. This method may only be called once.

varechoValue=awaitBuilder.UseShell<Bash>().UseExecutable<Echo>().WithArgument("😋").UseStandardOutputEncoding(Encoding.ASCII).ExecuteAsync();// echoValue is "????".

StartInfo Transform

You can arbitrarily change any options on theStartInfo of the process. This method may only be called once.

varechoValue=awaitBuilder.UseShell<Bash>().UseExecutable<Echo>().WithArgument(expected).UseStartInfoTransform(si=>{si.WorkingDirectory="/";}).ExecuteAsync();

Roll Your Own

You can also roll your ownIShell andIExecutable plugins. For example, it would be nice to implement akubectl wrapper.

publicinterfaceIKubectl:IExecutable<IKubectl>{IKubectlWithKubeConfig(stringconfigPath);IKubectlWithApply(stringyamlPath);}publicclassKubectl:Executable<IKubectl>,IKubectl{// Allows the `Executable` base class to "create and clone" a new instance for chanining.protectedoverrideExecutable<IKubectl>Create()=>newKubectl();// Sets the underlying executable of this executable type.publicKubectl():base("kubectl"){}publicIKubectlWithKubeConfig(stringconfigPath)=>this.WithArgument($"--kubeconfig={configPath}");publicIKubectlWithApply(stringyamlPath)=>this.WithArgument("apply","-f",yamlPath);}...var result=awaitBuilder.UseShell<Bash>().UseExecutable<Kubectl>().WithKubeConfig("kube_config.yaml").WithApply("my_app.yaml").ExecuteAsync();

License

The MIT License (MIT)Copyright (c) 2019 Aaron RoneyPermission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in allcopies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THESOFTWARE.

About

A .NET library that makes shelling out commands super easy and fluent.

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Contributors2

  •  
  •  

[8]ページ先頭

©2009-2025 Movatter.jp