Marcel - 更现代的 Linux ShellMarcel - 更现代的 Linux ShellMarcel - 更现代的 Linux ShellMarcel - 更现代的 Linux Shell
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2025年2月28日
类别
  • 未分类
标签

Marcel - 更现代的 Linux Shell

Marcel 是一个新的外壳。它在很多方面与传统 shell 相似,但有一些不同之处:

  • 管道:所有 shell 都使用管道将文本从一个命令的输出发送到另一个命令的输入。 Marcel 通过管道传输结构化数据而不是字符串。
  • Python:Marcel 用 Python 实现,并以多种方式公开 Python。如果您的命令中需要一些逻辑,marcel 允许您用 Python 表达它。
  • 脚本编写:Marcel 采用了一种不同寻常的脚本编写方法。当然,您可以简单地在文本文件中编写一系列 marcel 命令并执行它们。但 Marcel 还以 Python 模块的形式提供了 API。您可以导入此模块来以比普通 Python 更方便的方式执行 Python 脚本。

Marcel 已获得 GPLv3 许可。

在 Linux 中安装 Marcel Modern Shell

Marcel 需要 Python 3.6 或更高版本。它是在 Linux 上开发和测试的,并且主要适用于 macOS。 (如果您想帮助移植到Windows,或修复macOS缺陷,请与我们联系。)

要安装 marcel 供您自己使用:

python3 -m pip install marcel

或者,如果您想为所有用户安装(例如,安装到 /usr/local):

sudo python3 -m pip install --prefix /usr/local marcel

安装 marcel 后,通过运行命令 marcel 检查它是否正常工作,然后在 marcel 提示符下运行 版本命令:

marcel

Marcel Shell 的定制

您可以在文件~/.marcel.py中自定义marcel,该文件在启动时读取(并在修改时重新读取)。从文件名可以看出,marcel 的定制是用 Python 完成的。

您可能想做的一件事是自定义提示。为此,您可以将一个列表分配给 PROMPT 变量。例如,如果您希望提示符为当前目录,以绿色打印,后跟以蓝色打印的 >:

PROMPT = [
    Color(0, 4, 0),
    lambda: PWD,
    Color(0, 2, 5),
    '> '
]

生成的提示如下所示:

这取代了您需要在 bash 中执行的难以理解的 PS1 配置。 Color(0, 4, 0) 指定绿色,(参数为RGB值,范围为0-5强>)。 PWD 是代表当前目录的环境变量,并在该变量前加上 lambda: 前缀会生成一个函数,每次显示提示时都会对其进行评估。

~/.marcel.py 还可以导入 Python 模块。例如,如果您想在 marcel 命令中使用 math 模块的函数:

from math import *

完成此操作后,您可以引用该模块中的符号,例如圆周率:

请注意,pi 带括号。一般来说,marcel 使用括号来分隔 Python 表达式。因此,(pi) 计算检索变量 pi 值的 Python 表达式。您还可以通过这种方式访问传统的环境变量,例如(USER) 和 (HOME),或任何依赖于 marcel 命名空间中符号的有效 Python 表达式。

当然,您可以定义自己的符号。例如,如果您将此函数定义放在 ~/.marcel.py 中:

def factorial(n):
    f = 1
    for i in range(1, n + 1):
        f *= i
    return f

然后您可以在命令行上使用阶乘函数,例如

马塞尔外壳示例

在这里,我们将学习 marcel shell 中的一些命令示例。

按扩展名查找文件大小

递归地探索当前目录,按扩展名对文件进行分组(例如 .txt、.py 等),并计算每组的总文件大小。

您可以在 marcel 中执行此操作,如下所示:

ls 运算符生成 File 对象流(-fr 表示递归访问目录,并仅返回文件)。

File 对象通过管道传送到下一个命令,map。 map 在最外面的括号中指定一个 Python 函数,它将每个文件映射到一个包含文件扩展名及其大小的元组。 (Marcel 允许省略 lambda 关键字。)

red(减少)运算符按元组的第一部分(扩展)进行分组,然后对每组内的大小求和。结果按扩展名排序。

主机可执行文件和 Marcel 管道

管道可能包含 marcel 运算符和主机可执行文件的混合体。运算符通过管道传输对象,但在运算符/可执行文件边界处,marcel 通过管道传输字符串。

例如,此命令组合了运算符和可执行文件,并列出 shell 为 /bin/bash 的用户的用户名。

cat /etc/passwd \
| map (line: line.split(':')) \
| select (*line: line[-1] == '/bin/bash') \
| map (*line: line[0]) \
| xargs echo

cat 是一个 Linux 可执行文件。它读取 /etc/passwd,并且 marcel 将其内容向下游传送到 marcel 操作符映射。

map 的括号参数是一个 Python 函数,它在 : 分隔符处分割行,产生 7 元组。 select 是一个 marcel 运算符,其参数是一个 Python 函数,用于标识最后一个字段为 /bin/bash 的元组。

下一个运算符,另一个映射保留每个输入元组的用户名字段。最后,xargs echo 将传入的用户名组合成一行,并打印到标准输出。

在 Marcel Shell 中编写脚本

虽然 Python 有时被认为是一种脚本语言,但它实际上并不能很好地实现这一目的。问题是从 Python 运行 shell 命令和其他可执行文件很麻烦。您可以使用 os.system(),它很简单,但通常不足以处理 stdin、stdout 和 stderr。 subprocess.Popen() 功能更强大,但使用起来更复杂。

Marcel 的方法是提供一个将 marcel 运算符与 Python 语言功能集成的模块。回顾一下之前的示例,下面是按扩展名计算文件大小总和的 Python 代码:

from marcel.api import *

for ext, size in (ls(file=True, recursive=True)
                  | map(lambda f: (f.suffix, f.size))
                  | red('.', '+')):
    print(f'{ext}: {size})

除了语法约定之外,shell 命令与以前相同。所以 ls -fr 变成 ls(file=True, recursive=True)。地图和红色运算符也在那里,通过管道连接,就像 shell 版本中一样。整个 shell 命令(ls … red) 生成一个 Python 迭代器,以便该命令可以与 Python 的 for 循环一起使用。

使用 Marcel Shell 访问数据库

您可以将数据库访问与 marcel 管道集成。首先,您需要在配置文件 ~/.marcel.py 中配置数据库访问,例如

define_db(name='jao',
          driver='psycopg2',
          dbname='acme',
          user='jao')

DB_DEFAULT = 'jao'

这将使用 psycopg2 驱动程序配置对名为 acme 的 Postgres 数据库的访问。来自 marcel 的连接将使用 jao 用户进行,数据库配置文件名为 jao。 (如果未指定配置文件,则 DB_DEFAULT 将 jao 数据库配置文件指定为要使用的数据库配置文件。)完成此配置后,现在可以使用 sql 运算符查询数据库,例如

sql 'select part_name, quantity from part where quantity < 10' \
| out --csv –-file ~/reorder.csv

此命令查询名为 part 的表,并将查询结果以 CSV 格式转储到文件 ~/reorder.csv 中。

使用 Marcel Shell 进行远程访问

与数据库访问类似,远程访问可以在~/.marcel.py中配置。例如,这配置了 4 节点集群:

define_remote(name='lab',
              user='frankenstein',
              identity='/home/frankenstein/.ssh/id_rsa',
              host=['10.0.0.100', 
                    '10.0.0.101',
                    '10.0.0.102',
                    '10.0.0.103'])

该集群可以在 marcel 命令中被识别为实验室。 user 和identity 参数指定登录信息,host 参数指定集群上节点的IP 地址。

集群配置完成后,所有节点都可以同时运行。例如,要获取集群中的进程 pid 和命令行列表:

@lab [ps | map (proc: (proc.pid, proc.commandline))]

这将返回(IP 地址、PID、命令行)元组流。

欲了解更多信息,请访问:

  • https://www.marceltheshell.org/
  • https://github.com/geophile/marcel

Marcel 是一个相当新的项目,正在积极开发中。如果您想提供帮助,请联系我们。

©2015-2025 艾丽卡 support@alaica.com