├── .github └── workflows │ ├── BuildAndRunTests.yml │ ├── PublishIncrementalNuget.yml │ ├── PublishNuget.yml │ └── PublishTemplates.yml ├── .gitignore ├── CShell.sln ├── LICENSE ├── README.md ├── Sample ├── Program.cs └── Sample.csproj ├── Tests └── CShell.Tests │ ├── CShell.Tests.cs │ ├── CShell.Tests.csproj │ ├── CShellGlobal.Tests.cs │ ├── Command.Tests.cs │ ├── CommandGlobal.Tests.cs │ └── test │ ├── TestA.txt │ ├── TestB.txt │ ├── sleep.deps.json │ ├── sleep.dll │ ├── sleep.exe │ ├── sleep.runtimeconfig.json │ └── subfolder │ ├── TestC.txt │ ├── TestD.txt │ └── subfolder2 │ ├── TestE.txt │ └── TestF.txt ├── azure-pipelines.yml ├── src ├── CShell.cs ├── CShell.csproj ├── CommandExtensions.cs ├── CommandResultException.cs ├── CommandResultExtensions.cs ├── Globals.cs └── icon.png ├── template ├── CShell.Template │ ├── CShell.Template.nuspec │ ├── README.md │ ├── content │ │ ├── .template.config │ │ │ └── template.json │ │ └── CShellTemplate.csx │ ├── icon.png │ └── templates ├── CShellTemplate ├── CShellTemplate.cmd └── pack.cmd └── turtle.png /.github/workflows/BuildAndRunTests.yml: -------------------------------------------------------------------------------- 1 | name: BuildAndRunTests 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | paths: 9 | - src/** 10 | pull_request: 11 | branches: [ "main" ] 12 | paths: 13 | - src/** 14 | 15 | jobs: 16 | build: 17 | runs-on: ubuntu-latest 18 | 19 | steps: 20 | - name: Checkout CShell 21 | uses: actions/checkout@v4 22 | 23 | - name: Setup .NET 24 | uses: actions/setup-dotnet@v3 25 | with: 26 | dotnet-version: 8.0.x 27 | 28 | - name: Restore dependencies 29 | run: dotnet restore CShell.sln 30 | 31 | - name: Build 32 | run: dotnet build --no-restore CShell.sln --property WarningLevel=0 33 | 34 | - name: Test 35 | run: dotnet test --no-build --verbosity normal CShell.sln 36 | -------------------------------------------------------------------------------- /.github/workflows/PublishIncrementalNuget.yml: -------------------------------------------------------------------------------- 1 | name: Publish Incremental Nuget 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v4 12 | 13 | - name: Setup .NET 14 | uses: actions/setup-dotnet@v3 15 | with: 16 | dotnet-version: 8.0.x 17 | 18 | - name: Bump build version 19 | id: bump 20 | uses: vers-one/dotnet-project-version-updater@v1.5 21 | with: 22 | files: | 23 | "**/CShell.csproj" 24 | version: bump-build 25 | 26 | - name: Restore dependencies 27 | run: dotnet restore CShell.sln 28 | 29 | - name: Build 30 | run: dotnet build CShell.sln -c Release --no-restore 31 | 32 | - name: dotnet pack 33 | run: | 34 | dotnet pack --no-build CShell.sln -c Release -o packages --include-symbols --property WarningLevel=0 35 | 36 | - name: Publish NuGet and symbols 37 | id: nuget-push 38 | uses: edumserrano/nuget-push@v1 39 | with: 40 | api-key: '${{ secrets.NUGET_KEY }}' 41 | working-directory: 'packages' 42 | fail-if-exists: false 43 | 44 | - name: Commit new version changes 45 | run: | 46 | git config --global user.name "Github Action" 47 | git config --global user.email "tomlm@users.noreply.github.com" 48 | git commit -a -m "Bumped version for published nuget artifacts" 49 | git push 50 | -------------------------------------------------------------------------------- /.github/workflows/PublishNuget.yml: -------------------------------------------------------------------------------- 1 | name: Publish Nuget 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build: 8 | runs-on: windows-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v4 12 | 13 | - name: Setup .NET 14 | uses: actions/setup-dotnet@v3 15 | with: 16 | dotnet-version: 8.0.x 17 | 18 | - name: Setup NuGet.exe for use with actions 19 | uses: NuGet/setup-nuget@v2.0.0 20 | 21 | - name: Restore dependencies 22 | run: dotnet restore CShell.sln 23 | 24 | - name: Build 25 | run: dotnet build CShell.sln -c Release --no-restore 26 | 27 | - name: dotnet pack 28 | run: | 29 | dotnet pack --no-build CShell.sln -c Release -o packages --include-symbols --property WarningLevel=0 30 | 31 | #- name: nuget pack template 32 | # run: | 33 | # nuget pack template/CShell.Template/CShell.Template.nuspec -OutputDirectory packages 34 | 35 | - name: Publish NuGet and symbols 36 | id: nuget-push 37 | uses: edumserrano/nuget-push@v1 38 | with: 39 | api-key: '${{ secrets.NUGET_KEY }}' 40 | working-directory: 'packages' 41 | fail-if-exists: false 42 | 43 | -------------------------------------------------------------------------------- /.github/workflows/PublishTemplates.yml: -------------------------------------------------------------------------------- 1 | name: Publish Templates 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build: 8 | runs-on: windows-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v4 12 | 13 | - name: Setup NuGet.exe for use with actions 14 | uses: NuGet/setup-nuget@v2.0.0 15 | 16 | - name: nuget pack 17 | run: | 18 | nuget pack template/CShell.Template/CShell.Template.nuspec -OutputDirectory packages 19 | 20 | - name: Publish NuGet and symbols 21 | id: nuget-push 22 | uses: edumserrano/nuget-push@v1 23 | with: 24 | api-key: '${{ secrets.NUGET_KEY }}' 25 | working-directory: 'packages' 26 | fail-if-exists: false 27 | 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | ecf/ 24 | rcf/ 25 | 26 | # Visual Studio 2015 cache/options directory 27 | .vs/ 28 | 29 | # MSTest test Results 30 | [Tt]est[Rr]esult*/ 31 | [Bb]uild[Ll]og.* 32 | 33 | # NUNIT 34 | *.VisualState.xml 35 | TestResult.xml 36 | 37 | # Build Results of an ATL Project 38 | [Dd]ebugPS/ 39 | [Rr]eleasePS/ 40 | dlldata.c 41 | 42 | # .NET Core 43 | *.lock.json 44 | artifacts/ 45 | **/Properties/launchSettings.json 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opensdf 80 | *.sdf 81 | *.cachefile 82 | 83 | # Visual Studio profiler 84 | *.psess 85 | *.vsp 86 | *.vspx 87 | 88 | # TFS 2012 Local Workspace 89 | $tf/ 90 | 91 | # Guidance Automation Toolkit 92 | *.gpState 93 | 94 | # ReSharper is a .NET coding add-in 95 | _ReSharper*/ 96 | *.[Rr]e[Ss]harper 97 | *.DotSettings.user 98 | 99 | # JustCode is a .NET coding add-in 100 | .JustCode 101 | 102 | # TeamCity is a build add-in 103 | _TeamCity* 104 | 105 | # DotCover is a Code Coverage Tool 106 | *.dotCover 107 | 108 | # NCrunch 109 | _NCrunch_* 110 | .*crunch*.local.xml 111 | 112 | # MightyMoose 113 | *.mm.* 114 | AutoTest.Net/ 115 | 116 | # Web workbench (sass) 117 | .sass-cache/ 118 | 119 | # Installshield output folder 120 | [Ee]xpress/ 121 | 122 | # DocProject is a documentation generator add-in 123 | DocProject/buildhelp/ 124 | DocProject/Help/*.HxT 125 | DocProject/Help/*.HxC 126 | DocProject/Help/*.hhc 127 | DocProject/Help/*.hhk 128 | DocProject/Help/*.hhp 129 | DocProject/Help/Html2 130 | DocProject/Help/html 131 | 132 | # Click-Once directory 133 | publish/ 134 | 135 | # Publish Web Output 136 | *.[Pp]ublish.xml 137 | ## TODO: Comment the next line if you want to checkin your 138 | ## web deploy settings but do note that will include unencrypted 139 | ## passwords 140 | ## TODO: note that next line is commented out, but at line ~283 (Azure publish profiles) the same file type is uncommented. 141 | #*.pubxml 142 | 143 | ## ignore imporeted publish xml files 144 | *intercom-botdirectory-scratch\ -\ FTP.pubxml 145 | *intercom-botdirectory-scratch\ -\ Web\ Deploy.pubxml 146 | 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | 158 | # Windows Azure Build Output 159 | csx/ 160 | *.build.csdef 161 | 162 | # Windows Store app package directory 163 | AppPackages/ 164 | 165 | # Visual Studio cache files 166 | # files ending in .cache can be ignored 167 | *.[Cc]ache 168 | # but keep track of directories ending in .cache 169 | !*.[Cc]ache/ 170 | 171 | # Others 172 | ClientBin/ 173 | [Ss]tyle[Cc]op.* 174 | ~$* 175 | *~ 176 | *.dbmdl 177 | *.dbproj.schemaview 178 | *.jfm 179 | *.pfx 180 | *.publishsettings 181 | orleans.codegen.cs 182 | 183 | # Since there are multiple workflows, uncomment next line to ignore bower_components 184 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 185 | #bower_components/ 186 | 187 | # RIA/Silverlight projects 188 | Generated_Code/ 189 | 190 | # Backup & report files from converting an old project file 191 | # to a newer Visual Studio version. Backup files are not needed, 192 | # because we have git ;-) 193 | _UpgradeReport_Files/ 194 | Backup*/ 195 | UpgradeLog*.XML 196 | UpgradeLog*.htm 197 | 198 | # SQL Server files 199 | *.mdf 200 | *.ldf 201 | *.ndf 202 | 203 | # Business Intelligence projects 204 | *.rdl.data 205 | *.bim.layout 206 | *.bim_*.settings 207 | 208 | # Microsoft Fakes 209 | FakesAssemblies/ 210 | 211 | # GhostDoc plugin setting file 212 | *.GhostDoc.xml 213 | 214 | # Node.js Tools for Visual Studio 215 | .ntvs_analysis.dat 216 | node_modules/ 217 | 218 | # Typescript v1 declaration files 219 | typings/ 220 | 221 | # Visual Studio 6 build log 222 | *.plg 223 | 224 | # Visual Studio 6 workspace options file 225 | *.opt 226 | 227 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 228 | *.vbw 229 | 230 | # Visual Studio LightSwitch build output 231 | **/*.HTMLClient/GeneratedArtifacts 232 | **/*.DesktopClient/GeneratedArtifacts 233 | **/*.DesktopClient/ModelManifest.xml 234 | **/*.Server/GeneratedArtifacts 235 | **/*.Server/ModelManifest.xml 236 | _Pvt_Extensions 237 | 238 | # Paket dependency manager 239 | .paket/paket.exe 240 | paket-files/ 241 | 242 | # FAKE - F# Make 243 | .fake/ 244 | 245 | # JetBrains Rider 246 | .idea/ 247 | *.sln.iml 248 | 249 | # CodeRush 250 | .cr/ 251 | 252 | # Python Tools for Visual Studio (PTVS) 253 | __pycache__/ 254 | *.pyc 255 | 256 | # Cake - Uncomment if you are using it 257 | # tools/** 258 | # !tools/packages.config 259 | 260 | # Telerik's JustMock configuration file 261 | *.jmconfig 262 | 263 | # BizTalk build output 264 | *.btp.cs 265 | *.btm.cs 266 | *.odx.cs 267 | *.xsd.cs 268 | # LightSwitch generated files 269 | GeneratedArtifacts/ 270 | _Pvt_Extensions/ 271 | ModelManifest.xml 272 | /Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll 273 | /Microsoft.CodeDom.Providers.DotNetCompilerPlatform.xml 274 | /PublishScripts/Scripts/Deploy-AzureResourceGroup-5.ps1 275 | /PublishScripts 276 | 277 | # User-specific files 278 | Documentation/Doxygen_warnings.txt 279 | 280 | # Build results 281 | Documentation/docs/ 282 | 283 | # Azure publish profiles 284 | *.pubxml 285 | PublishProfiles/ 286 | 287 | appsettings.local.json -------------------------------------------------------------------------------- /CShell.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.10.35201.131 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CShell", "src\CShell.csproj", "{9705E191-6CF0-4F55-B3E2-C34A81A7FE28}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CShell.Tests", "Tests\CShell.Tests\CShell.Tests.csproj", "{3EC7173A-D8DB-4CFB-B63E-CBE688AD5C3D}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E8F4E9C2-526E-4C7C-AB2D-4455D1528BD6}" 11 | ProjectSection(SolutionItems) = preProject 12 | README.md = README.md 13 | EndProjectSection 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample", "Sample\Sample.csproj", "{945CEB6E-0534-45AE-A63E-AE8F08A850CC}" 16 | EndProject 17 | Global 18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 19 | Debug|Any CPU = Debug|Any CPU 20 | Release|Any CPU = Release|Any CPU 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {9705E191-6CF0-4F55-B3E2-C34A81A7FE28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {9705E191-6CF0-4F55-B3E2-C34A81A7FE28}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {9705E191-6CF0-4F55-B3E2-C34A81A7FE28}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {9705E191-6CF0-4F55-B3E2-C34A81A7FE28}.Release|Any CPU.Build.0 = Release|Any CPU 27 | {3EC7173A-D8DB-4CFB-B63E-CBE688AD5C3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 28 | {3EC7173A-D8DB-4CFB-B63E-CBE688AD5C3D}.Debug|Any CPU.Build.0 = Debug|Any CPU 29 | {3EC7173A-D8DB-4CFB-B63E-CBE688AD5C3D}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {3EC7173A-D8DB-4CFB-B63E-CBE688AD5C3D}.Release|Any CPU.Build.0 = Release|Any CPU 31 | {945CEB6E-0534-45AE-A63E-AE8F08A850CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 32 | {945CEB6E-0534-45AE-A63E-AE8F08A850CC}.Debug|Any CPU.Build.0 = Debug|Any CPU 33 | {945CEB6E-0534-45AE-A63E-AE8F08A850CC}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {945CEB6E-0534-45AE-A63E-AE8F08A850CC}.Release|Any CPU.Build.0 = Release|Any CPU 35 | EndGlobalSection 36 | GlobalSection(SolutionProperties) = preSolution 37 | HideSolutionNode = FALSE 38 | EndGlobalSection 39 | GlobalSection(ExtensibilityGlobals) = postSolution 40 | SolutionGuid = {F21757E8-6291-4BCC-AAF7-C9C0B805D67C} 41 | EndGlobalSection 42 | EndGlobal 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Tom Laird-McConnell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # CShell 4 | CShell creates a runtime environment to make it easy to create C# based shell style scripts. 5 | 6 | # Description 7 | CShell is built using [MedallionShell](https://github.com/madelson/MedallionShell) and runs great using [dotnet-script](https://github.com/filipw/dotnet-script) (.csx) giving 8 | you a great cross platform C# alternative to powershell and bash scripts. 9 | 10 | CShell provides: 11 | * The concept of a current folder with relative commands for navigating and manipulating files and folders 12 | * The ability to smoothly invoke processes and pipe 13 | * Helpers to make it easy to work with the output of processes 14 | 15 | By maintaining the concept of a current folder all file and folder commands can be take absolute or 16 | relative paths just like a normal shell. 17 | 18 | ### Properties 19 | CShell exposes 3 properties which are the working environment of your script. The CurrentFolder is used to resolve relative paths for 20 | most methods, so if you call **MoveFile(@"..\foo.txt", @"..\..\bar")** it will resolve the paths and execute just like a normal shell. 21 | 22 | | Property | Description | 23 | |-------------------|---------------------------------------------- | 24 | | **CurrentFolder** | The current folder as a DirectoryInfo object | 25 | | **FolderHistory** | List of folder paths you have navigated to | 26 | | **FolderStack** | current stack from Push/Pop operations | 27 | | **Echo** | Controls whether commands are echoed to output | 28 | | **ThrowOnError** | Controls whether to throw exception when commands have non-sucess error code | 29 | 30 | ### Folder Methods 31 | CShell defines a number of methods which work relative to the current folder to make it easy 32 | to manipulate folders. 33 | 34 | | Method | Description | 35 | |-------------|------------------------------------------------------------------------------| 36 | | **cd()** | Change the current folder with relative or absolute path | 37 | | **md()** | Create a folder relative to current folder | 38 | | **rd()** | Delete a folder relative to current folder | 39 | | **pushd()** | Push the current folder onto the stack and change folder to the new one | 40 | | **popd()** | Pop the current folder off the stack and change the folder the popped folder | 41 | 42 | ### File Methods 43 | CShell defines a number of methods which work relative to the current folder to make it easy 44 | to manipulate files. 45 | 46 | | Method | Description | 47 | |--------------|----------------------------------------------| 48 | | **copy()** | Copy a file relative to current folder | 49 | | **move()** | Move a file relative to current folder | 50 | | **rename()** | Move a file relative to current folder | 51 | | **delete()** | Delete a file relative to current folder | 52 | | **exists()** | does a file relative to current folder exist | 53 | | **type()** | type a file to standardout | 54 | | **cat()** | cat a file to standardout | 55 | 56 | 57 | ### Process Methods 58 | CShell is built using [MedallionShell](https://github.com/madelson/MedallionShell), which provides a great set of functionality for easily invoking 59 | processes and piping data between them. CShell adds on location awareness and helper methods 60 | to make it even easier to work with the output of processes. 61 | 62 | | Method | Description | 63 | |------------------|--------------------------------------------------------------------------------------------------| 64 | | **ReadFile()/cat()/type()** | read a file and create a stream | 65 | | **echo(text/lines/stream)** | echo text,lines from memory to a stream | 66 | | **Run(program, arg1, ..., argN)** | run a program directly with the given args (aka Process.Start(program, args) | 67 | | **Start(program, arg1, ..., argN)** | run a DETACHED program directly with the given args (aka Process.Start(program, args)| 68 | | **Cmd(cmd)** | run the cmd inside a cmd.exe, allow you to execute shell commands (like dir /b *.* | 69 | | **Bash(bash)** | run the program in bash environment, allow you to execute bash shell commands (like ls -al * | 70 | 71 | ```CSharp 72 | // Invoke multiple commands using fluent style 73 | var cmd1= await Run("cmd1", "args1") 74 | .PipeTo("cmd2", "args2", "args3") 75 | .PipeTo("cmd3", "args4"); 76 | var result1 = await cmd1.AsResult(); 77 | 78 | // we can even chain commands together with the pipe operator 79 | var cmd2 = await Run("cmd1", "args1") 80 | | Run("cmd2", "args2", "args3") 81 | | Run("cmd3", "args4"); 82 | var result2 = await cmd2.AsResult(); 83 | 84 | // we can even chain commands together with the > operator 85 | var = await Run("cmd1", "args1") 86 | > Run("cmd2", "args2", "args3") 87 | > Run("cmd3", "args4"); 88 | var result3 = await cmd3.AsResult(); 89 | ``` 90 | 91 | The CommandResult object has StandardOutput, StandardError information for further processing. 92 | 93 | #### Working with results 94 | CShell adds on helper methods to make it even easier to work with the result of a command chain. 95 | 96 | | Method | Description | 97 | |------------------|------------------------------------------------------------------------------| 98 | | **Execute(log)** | get the CommandResult (with stdout/stderr) of the last command | 99 | | **AsString(log)** | get the standard out of the last command a string | 100 | | **AsJson(log)** | JSON Deserialize the standard out of the last command into a JObject/dynamic | 101 | | **AsJson\(log)** | JSON Deserialize the standard out of the last command into a typed T | 102 | | **AsXml\(log)** | XML Deserialize the standard out of the last command intoa typed T | 103 | | **AsFile()** | Write the stdout/stderr of the last command to a file | 104 | 105 | 106 | To call a program you await on: 107 | 1. call ReadFile()/Run()/Cmd()/Bash()/echo() 108 | 2. call any chaining commands 109 | 3. end with a result call like Execute()/AsJson()/AsString()/AsXml()etc. 110 | 111 | The result methods all take a log argument is passed set to true then the commands output will be written to standard out. 112 | 113 | ```CSharp 114 | global using static CShellNet.Globals; 115 | using CShellNet; 116 | 117 | Console.WriteLine("Hello world!"); 118 | 119 | // run a command and interpret the json as an AccountInfo object 120 | var account = await Cmd("az account show").AsJson(); 121 | 122 | // run a command and interpret the XML as an AccountInfo object 123 | var account2 = await Cmd("az account show -o xml").AsXml(); 124 | 125 | // run a command interpret the result as a string. 126 | var accountString = await Cmd("az account show").AsString(); 127 | 128 | // run a command and get back the CommandResult which has Succes, StatusCode, StandardInput and StandardError. 129 | var result = await (Run("x", "foo") | Cmd("az account show")).AsResult(); 130 | if(result.Sucess) 131 | { 132 | var output = result.StandardOutput; 133 | ... 134 | } 135 | ``` 136 | 137 | 138 | ## CShell + dotnet-script == awesome 139 | CShell is a dotnet library which can be used in any .net program, but it is super useful to use from a dotnet-script (.csx) file. 140 | There is a dotnet template to make it super easy to create a .csx file with CShell all set up to use. 141 | 142 | To install dotnet-script support 143 | 144 | **```dotnet tool install -g dotnet-script```** 145 | 146 | To install the csx template 147 | 148 | **```dotnet new --install CShell.Template```** 149 | 150 | To invoke the template 151 | 152 | **``` dotnet new cshell ```** 153 | 154 | > NOTE: If you want debug support from visual studio code simply run **dotnet script init** in the same folder. 155 | 156 | ```csharp 157 | #r "nuget: CShell, 1.5.0" 158 | global using static CShellNet.Globals; 159 | using CShellNet; 160 | 161 | Console.WriteLine("Hello world!"); 162 | foreach (var arg in Args) 163 | { 164 | md(arg); 165 | ... 166 | } 167 | ``` 168 | 169 | 170 | ### Registering .csx files to be executable on windows 171 | You can register dotnet-script as the default handler for .csx files by running these commands: 172 | ```cmd 173 | dotnet script register 174 | ``` 175 | 176 | After registering you can simple type **your.csx** to execute your cshell program. 177 | 178 | > NOTE: dotnet script register will fail if visual studio code has been installed, as it registers 179 | > itself as an editor for .csx files in a way that causes the dotnet script register command to not work correctly. 180 | > To fix this execute: 181 | > ```cmd 182 | > reg delete HKCU\Software\classes\.csx /f 183 | > dotnet script register 184 | > ``` 185 | 186 | ### Registering .csx files to be executable on MacOS/Linux 187 | On Linux/Mac you can make a .csx file executable by 188 | 1. adding a shebang line at the top of the file 189 | 2. running **chmod +x {yourfile}.csx**. 190 | 3. running **dos2unix {yourfile}.csx** to make sure it has unix line endings (LF \n) not windows (CRLF \r\n) line endings 191 | 192 | ```bash 193 | #!/usr/bin/env dotnet-script 194 | #r "nuget: CShell, 1.5.0" 195 | global using static CShellNet.Globals; 196 | using CShellNet; 197 | ``` 198 | 199 | ### Short cut alias files 200 | Visual Studio Code requires the script file to have .csx extension, but you can create an alias wrapper for the script file 201 | to make it that it can be invoked without the .csx extension. 202 | 203 | #### Creating an script alias on Windows 204 | To create an alias for **example.csx** on Windows simply create a file **example.cmd** 205 | ```cmd 206 | @dotnet script %~dp0\example.csx 207 | ``` 208 | 209 | #### Creating an script alias on Linux/MacOS 210 | To create an alias for **example.csx** on Linux/MacOS simply create a file **example** 211 | ```bash 212 | #!/usr/bin/env bash 213 | BASEDIR=$(dirname $BASH_SOURCE) 214 | dotnet script $BASEDIR/example.csx 215 | ``` 216 | and mark it as executable 217 | ```bash 218 | chmod +x example.csx 219 | ``` 220 | 221 | ## CHANGELOG 222 | 223 | ### V1.5.2 224 | * Added Exists() methods to global 225 | 226 | ### V1.5.0 227 | * Added Exists() methods 228 | 229 | ### V1.4.0 230 | * Added Start() method for detached processess (you can monitor process but not access input/output) 231 | * Added Run(Action