Skip to content

Latest commit

 

History

75 提交

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

仓库 files navigation

ShellKit

Build Status Coverage Status 问题 Status License Contact
Donate-Patreon Donate-Gratipay Donate-Paypal

关于

Objective-C framework for running shell scripts.

Terminal

Documentation

Documentation and API reference can be found at: http://doc.xs-labs.com/ShellKit/

Code Examples

ShellKit provides a test executable.
For complete examples, please take a look at the source code.

Shell informations

Various shell informations, like paths for commands, can be retrieved using the SKShell class:

[ [ SKShell currentShell ] commandIsAvailable: @"xcodebuild" ]

NSString * path = [ [ SKShell currentShell ] pathForCommand: @"xcodebuild" ]

Running simple commands

Arbitrary shell commands can be run using the SKShell class.
Note that commands are executed using the shell defined in the SHELL environment variable, invoked as a login shell.
Data for stdin can be provided; stdout and stderr can be retrieved.

[ [ SKShell currentShell ] runCommand: @"ls -al"
                           completion: ^( int status, NSString * output, NSString * error )
    {
        NSLog( @"%i", status );
        NSLog( @"%@", output );
        NSLog( @"%@", error );
    }
];

Running shell script tasks

A shell command can by run by using the SKTask object:

SKTask * task;

task = [ SKTask taskWithShellScript: @"ls -al" ];

[ task run ];

The task is run synchronously, and its output, if any, will be automatically printed to stdout.

The task will print the executed command prior to running, and print a status message once it's terminated, along with the elapsed time:

[ ShellKit ]> 🚦  Running task: ls -al
total 536
drwxr-xr-x  5 macmade  staff     170 May 11 23:49 .
drwxr-xr-x@ 4 macmade  staff     136 May 11 22:18 ..
-rwxr-xr-x  1 macmade  staff  124624 May 11 23:49 ShellKit-Test
drwxr-xr-x  7 macmade  staff     238 May 11 23:48 ShellKit.framework
-rw-r--r--  1 macmade  staff  143936 May 11 23:48 libShellKit-Static.a
[ ShellKit ]> ✅  Task completed successfully (63 ms)

A task can have sub-tasks, to try to recover from a failure:

SKTask * task;

task = [ SKTask taskWithShellScript: @"false" recoverTask: [ SKTask taskWithShellScript: @"true" ] ];

[ task run ];

Here, the false task will obviously fail, but it will then execute the true task, set as recovery.
As true will succeed, the false task will also succeed:

[ ShellKit ]> 🚦  Running task: false
[ ShellKit ]> ⚠️  Task failed - Trying to recover...
[ ShellKit ]> 🚦  Running task: true
[ ShellKit ]> ✅  Task completed successfully (66 ms)
[ ShellKit ]> ✅  Task recovered successfully (66 ms)

Optional tasks

A task can be marked as optional by using the SKOptionalTask.
In such a case, the task will succeed, regardless of its exit status:

SKOptionalTask * task;
            
task = [ SKOptionalTask taskWithShellScript: @"false" ];

[ task run ];
[ ShellKit ]> 🚦  Running task: false
[ ShellKit ]> ❌  Error - Task exited with status 1
[ ShellKit ]> ✅  Task is marked as optional - Not failing

Running task groups

Multiple tasks can be grouped in a SKTaskGroup object:

SKTask      * t1;
SKTask      * t2;
SKTaskGroup * group;

t1    = [ SKTask taskWithShellScript: @"true" ];
t2    = [ SKTask taskWithShellScript: @"true" ];
group = [ SKTaskGroup taskGroupWithName: @"task-group" tasks: @[ t1, t2 ] ];
        
[ group run ];

The group will try to run each task.
If a task fails, the whole group will also fail.

[ ShellKit ]> [ task-group ]> 🚦  Running 2 tasks
[ ShellKit ]> [ task-group ]> [ #1 ]> 🚦  Running task: true
[ ShellKit ]> [ task-group ]> [ #1 ]> ✅  Task completed successfully (64 ms)
[ ShellKit ]> [ task-group ]> [ #2 ]> 🚦  Running task: true
[ ShellKit ]> [ task-group ]> [ #2 ]> ✅  Task completed successfully (65 ms)
[ ShellKit ]> [ task-group ]> ✅  2 tasks completed successfully (132 ms)

Running task groups within task groups

A task group may also contain other task groups:

SKTask      * t1;
SKTask      * t2;
SKTaskGroup * g1;
SKTaskGroup * g2;

t1 = [ SKTask taskWithShellScript: @"true" ];
t2 = [ SKTask taskWithShellScript: @"true" ];
g1 = [ SKTaskGroup taskGroupWithName: @"child-group" tasks: @[ t1, t2 ] ];
g2 = [ SKTaskGroup taskGroupWithName: @"parent-group" tasks: @[ g1 ] ];
        
[ g2 run ];

The hierarchy of groups will be reflected by the prompt, like:

[ ShellKit ]> [ parent-group ]> [ #1 ]> [ child-group ]> [ #1 ]> 🚦  Running task: true

Note that task groups can also run custom classes, as long as they conform to the SKRunableObject protocol.

Variables substitution

A task may contain variables, that will be substituted when running.
A variable has the following form:

%{name}%

The variable name may contain letters from A to Z (uppercase or lowercase) and numbers from 0 to 9.

Variables are passed using the run: method of SKTask and SKTaskGroup.

SKTask * task;

task = [ SKTask taskWithShellScript: @"ls %{args}% %{dir}%" ];

[ task run: @{ @"args" : @"-al", @"dir" : @"/usr" } ];

In the example above, the executed script will be: ls -al /usr.

If no value is provided for a variable, the task will fail:

SKTask * task;

task = [ SKTask taskWithShellScript: @"echo %{hello}% %{foo}% %{bar}%" ];

[ task run: @{ @"hello" : @"hello, world" } ];
[ ShellKit ]> 🚦  Running task: echo hello, world %{foo}% %{bar}%
[ ShellKit ]> ⚠️  No value provided value for variable: foo
[ ShellKit ]> ⚠️  No value provided value for variable: bar
[ ShellKit ]> ❌  Error - Script contains unsubstituted variables

Printing messages

Messages can be printed very easily.
For this purpose, the SKShell class provides several methods, like the following one:

- ( void )printMessage: ( NSString * )format
          status:       ( SKStatus )status
          color:        ( SKColor )color,
                        ...;

The status represents an optional icon.
Colors can also be used, if the terminal supports it.

As an example:

[ [ SKShell currentShell ] printMessage: @"hello, %@"
                           status:       SKStatusDebug
                           color:        SKColorCyan,
                                         @"world"
];

will produce:

🚸 hello, world

Customising prompt

The prompt can be customised to reflect the hierarchy of the invoked commands.

For instance:

[ SKShell currentShell ].promptParts = @[ @"foo", @"bar" ];

Then, every printed message will be prefixed by:

[ foo ]> [ bar ]> ... message ...

License

ShellKit is released under the terms of the MIT license.

仓库 Infos

Owner:          Jean-David Gadina - XS-Labs
Web:            www.xs-labs.com
Blog:           www.noxeos.com
Twitter:        @macmade
GitHub:         github.com/macmade
LinkedIn:       ch.linkedin.com/in/macmade/
StackOverflow:  stackoverflow.com/users/182676/macmade

关于

Objective-C framework for running shell scripts.

Topics

Resources

Stars

89 stars

关注者

7 watching

复刻s

发布

贡献者

Languages