#shell #command #bash #proc-macro #strongly-typed #env-var

shellfn

类似于属性的proc宏,减少了调用shell命令并解析结果所需的代码量

2个版本

0.1.1 2019年2月16日
0.1.0 2019年2月16日

#476操作系统

Download history 51/week @ 2024-03-12 47/week @ 2024-03-19 56/week @ 2024-03-26 89/week @ 2024-04-02 28/week @ 2024-04-09 42/week @ 2024-04-16 50/week @ 2024-04-23 46/week @ 2024-04-30 49/week @ 2024-05-07 42/week @ 2024-05-14 53/week @ 2024-05-21 53/week @ 2024-05-28 32/week @ 2024-06-04 34/week @ 2024-06-11 34/week @ 2024-06-18 26/week @ 2024-06-25

132 每月下载量
6 个crate中使用了 (5 个直接使用)

MIT 许可证

51KB
606

概述

这是一个rust属性-like proc宏,减少了调用shell命令和解析结果所需的代码量。

它允许您使用强类型函数将任何语言的脚本包装起来。函数的参数设置为环境变量,脚本的输出结果可以解析为值或迭代器。

Crates.io license Build Status

文档

仓库

示例

基础

use shellfn::shell;
use std::error::Error;

#[shell]
fn list_modified(dir: &str) -> Result<impl Iterator<Item=String>, Box<Error>> { r#"
    cd $DIR
    git status | grep '^\s*modified:' | awk '{print $2}'
"# }

不同的解释器

use shellfn::shell;
use std::error::Error;

#[shell(cmd = "python -c")]
fn pretty_json(json: &str, indent: u8, sort_keys: bool) -> Result<String, Box<Error>> { r#"
import os, json

input = os.environ['JSON']
indent = int(os.environ['INDENT'])
sort_keys = os.environ['SORT_KEYS'] == 'true'
obj = json.loads(input)

print(json.dumps(obj, indent=indent, sort_keys=sort_keys))
 "# }

用法

您可以在具有

  • 仅包含一个表达式(表示要执行的脚本的字符串字面量)的函数体上使用 #[shell] 属性
  • 实现 .to_string() 方法的类型
  • 返回一个值,该值可以是 voidTResult<T, E>impl Iterator<Item=T>Result<impl Iterator<Item=T>>Result<impl Iterator<Item=Result<T, E>>> 带约束
T: FromStr,
<T as FromStr>::Err: StdError,
E: From<shellfn::Error<<T as FromStr>::Err>>,
  • 详细信息

#[shell] 属性执行以下操作

  1. 将每个参数设置为一个环境变量
  2. 运行shell命令
  3. 使用 std::process::Command 启动命令
  4. 根据返回类型,它可能会解析输出

大多数步骤都可以进行调整

  • 默认命令是 bash -c。您可以通过使用 cmd 参数来更改它
#[shell(cmd = "python -c")]
  • 默认情况下,脚本作为最后一个参数添加。您可以使用 PROGRAM 特殊变量在 cmd 参数中更改它
#[shell(cmd = "bash -c PROGRAM -i")]
  • 您可以在 cmd 参数中像在脚本中一样使用从函数参数设置的 env 变量
#[shell(cmd = "python -m $MODULE")]
fn run(module: &str)
  • 如果返回类型不是在 Result 中包含结果的一部分,您可以选择通过添加 no_panic 标志来抑制 panic
#[shell(no_panic)]

目前识别以下返回类型

返回类型 标志 解析失败时 错误退出码时 启动失败时 说明
- panic panic
no_panic -
() - panic panic
() no_panic -
Result<(), E> - 错误 错误
Result<(), E> no_panic - 错误 错误 1
T panic panic panic 2
T no_panic panic panic panic 1,2
Result<T, E> 错误 错误 错误 2
Result<T, E> no_panic 错误 错误 错误 1,2
Vec panic panic panic
Vec no_panic 跳过 忽略 空 Vec 3
Vec<Result<T, E>> 项错误 panic panic
Vec<Result<T, E>> no_panic 项错误 忽略 空 Vec
Result<Vec, E> panic 错误 错误
Result<Vec, E> no_panic 跳过 错误 错误
Result<Vec<Result<T, E1>>, E2> 项错误 错误 错误
Result<Vec<Result<T, E1>>, E2> no_panic 项错误 错误 错误 1
实现 Iterator<Item=T> panic panic panic
实现 Iterator<Item=T> no_panic 跳过 忽略 空迭代器 3
实现 Iterator<Item=Result<T, E>> 项错误 panic panic 3
实现 Iterator<Item=Result<T, E>> no_panic 项错误 忽略 空迭代器
Result<实现 Iterator<Item=T>, E> panic 忽略 错误
Result<实现 Iterator<Item=T>, E> no_panic 跳过 忽略 错误
Result<实现 Iterator<Item=Result<T, E1>>, E2> 项错误 忽略 错误
Result<实现 Iterator<Item=Result<T, E1>>, E2> no_panic 项错误 忽略 错误 1

词汇表

动作 含义
panic panic (.expect 或 panic!)
消费并忽略错误 (let _ = ...)
错误 返回错误
跳过 产生所有成功解析的项目,忽略解析失败 (filter_map)
空迭代器/Vec 返回空迭代器/向量
项错误 解析失败时,产生 Err
忽略 忽略退出码,对于退出码 0 和 != 0 的行为相同

说明

  1. no_panic 属性没有任何区别
  2. 它读取所有 stdout 后才产生任何失败
  3. 它产生所有项目,直到遇到错误或退出码

向量与迭代器

返回类型为 Vec 的变体与返回类型为 impl Iterator 的变体非常相似。主要区别是

  • impl Iterator 只在每次分配一个项目并立即在解析后产生它,而 Vec 则是逐行读取输出,但将解析后的输出存储在临时的 Vec 中
  • Vec 意识到退出码。当子进程以错误结束,impl Iterator 将停止产生值,而 Vec 将返回错误或 panic

贡献

所有贡献和评论都热烈欢迎!不要害怕在您发现错误或想改进此 crate 时打开问题或 PR。

许可证

MIT 许可证

版权所有 (c) 2017 Marcin Sas-Szymański

在此特此授予任何获得此软件及其相关文档副本(“软件”)的人免费处理该软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本,并允许向软件提供者提供软件的人这样做,前提是符合以下条件

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

本软件按“原样”提供,不提供任何形式的保证,无论是明示的、暗示的,还是包括但不限于适销性、适用于特定目的和非侵权的保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论该责任基于合同、侵权或其他任何原因,以及该软件或其使用或以其他方式与该软件相关的任何事件。

依赖关系

~6MB
~116K SLoC