# Shellmath
Introducing decimal arithmetic libraries for the Bash shell, because
they said it couldn't be done... and because:
.
![image info](./image.png)
## Quick-start guide
Download this project and source the file `shellmath.sh` into your shell script,
then fire away at the shellmath API!
The ___basic___ API looks like this:
```
_shellmath_add arg1 arg2 [...] argN
_shellmath_subtract arg1 arg2 # means arg1 - arg2
_shellmath_multiply arg1 arg2 [...] argN
_shellmath_divide arg1 arg2 # means arg1 / arg2
```
The ___extended___ API introduces one more function:
```
_shellmath_getReturnValue arg
```
This function optimizes away the need for ___$(___ subshelling ___)___ in order to capture `shellmath`'s output.
To use this feature, just be sure to set `__shellmath_isOptimized=1` at the top
of your script. (You can find an example in `faster_e_demo.sh`.)
Operands to the _shellmath_ functions can be integers or decimal
numbers presented in either standard or scientific notation:
```
_shellmath_add 1.009 4.223e-2
_shellmath_getReturnValue sum
echo "The sum is $sum"
```
Addition and multiplication are of arbitrary arity; try this on for size:
```
_shellmath_multiply 1 2 3 4 5 6
_shellmath_getReturnValue sixFactorial
echo "6 factorial is $sixFactorial"
```
Subtraction and division, OTOH, are exclusively binary operations.
## The demos
For a gentle introduction to `shellmath` run the demo `slower_e_demo.sh`
with a small whole-number argument, say 15:
```
$ slower_e_demo.sh 15
e = 2.7182818284589936
```
This script uses a few `shellmath` API calls to calculate *e*, the mathematical
constant also known as [Euler's number](https://oeis.org/A001113). The argument
*15* tells the script to evaluate the *15th-degree* Maclaurin polynomial for *e*.
(That's the Taylor polynomial centered at 0.) Take a look inside the script to
see how it uses the `shellmath` APIs.
There is another demo script very much like this one but *different*, and the
sensitive user can *feel* the difference. Try the following, but don't blink
or you'll miss it ;)
```
$ faster_e_demo.sh 15
e = 2.7182818284589936
```
Did you feel the difference? Try the `-t` option with both scripts; this will produce
timing statistics. Here are my results
when running from my minGW64 command prompt on Windows 10 with an Intel i3 Core CPU:
```
$ for n in {1..5}; do faster_e_demo.sh -t 15 2>&1; done | awk '/^real/ {print $2}'
0m0.055s
0m0.051s
0m0.056s
0m0.054s
0m0.054s
$ for n in {1..5}; do slower_e_demo.sh -t 15 2>&1; done | awk '/^real/ {print $2}'
0m0.498s
0m0.594s
0m0.536s
0m0.511s
0m0.580s
```
(When sizing up these timings, do keep in mind that ___we are timing the
calculation of e from its Maclaurin polynomial. Every invocation of either
script is exercising the shellmath arithmetic subroutines 31 times.___)
The comment header in `faster_e_demo.sh` explains the optimization and shows
how to put this faster version to work for you.
## Runtime efficiency competitive with awk and bc
The file `timingData.txt` captures the results of some timing experiments that compare
`shellmath` against the GNU versions of the calculators `awk` and `bc`. The experiments
exercised each of the arithmetic operations and captured the results in a shell variable.
The result summary below shows that `shellmath` is competitive with `awk` and runs faster
than `bc` in these experiments. (One commenter noted that the differences in execution speed
can be partially explained by the fact that `shellmath` and `awk` use finite precision
whereas `bc` uses arbitrary precision. Another factor in these measurements is the need to
subshell 'awk' and 'bc' to capture their results, whereas 'shellmath' writes directly to
the shell's global memory.)
Here are the run times of `shellmath` as a percentage of the `awk` and `bc` equivalents:
```
versus awk versus bc
Addition: 82.2% 40.6%
Subtraction: 95.9% 50.5%
Multiplication: 135.9% 73.3%
Division: 80.3% 43.2%
```
Astute observers will note the experiments provide approximations to the sum, difference,
product, and quotient of *pi* and *e*. Unfortunately I did not gain insight as to which
of these values, if any, are
[transcendental](https://en.wikipedia.org/wiki/Transcendental_number#Possible_transcendental_numbers).
You can find a deeper discussion of shellmath's runtime efficiency
[here](https://github.com/clarity20/shellmath/wiki/Shellmath-and-runtime-efficiency).
## Background
The Bash shell does not have built-in operators for decimal arithmetic, making it
something of an oddity among well-known, widely-used programming languages. For the most part,
practitioners in need of powerful computational building blocks have naturally opted
for *other* languages and tools. Their widespread availability has diverted attention
from the possibility of *implementing* decimal arithmetic in Bash and it's easy to assume
that this ***cannot*** be done:
+ From the indispensable _Bash FAQ_ (on _Greg's Wiki_): [How can I calculate with floating point numbers?](http://mywiki.wooledge.org/BashFAQ/022)
*"For most operations... an external program must be used."*
+ From Mendel Cooper's wonderful and encyclopedic _Advanced Bash Scripting Guide_:
[Bash does not understand floating point arithmetic. Use bc instead.](https://tldp.org/LDP/abs/html/ops.html#NOFLOATINGPOINT)
+ From a community discussion on Stack Overflow, _How do I use floating point division in bash?_
The user's [preferred answer](https://stackoverflow.com/questions/12722095/how-do-i-use-floating-point-division-in-bash#12722107)
is a good example of _prevailing thought_ on this subject.
Meanwhile,
+ Bash maintainer (BDFL?) Chet Ramey sounds a (brighter?) note in [The Bash Reference Guide, Section 6.5](https://tiswww.case.edu/php/chet/bash/bashref.html#Shell-Arithmetic)
by emphasizing what the built-in arithmetic operators ***can*** do.
But finally, a glimmer of hope:
+ A [diamond-in-the-rough](http://stackoverflow.com/a/24431665/3776858) buried elsewhere
on Stack Overflow.
This down-and-dirty milestone computes the decimal quotient of two integer arguments. At a casual
glance, it seems to have drawn inspiration from the [Euclidean algorithm](https://mathworld.wolfram.com/EuclideanAlgorithm.html)
for computing GCDs, an entirely different approach than `shellmath`'s.
Please try `shellmath` on for size and draw your own conclusions!
## How it works
`shellmath` splits decimal numbers into their integer and fractional parts,
performs the appropriate integer operations on the parts, and recombines the results.
(In the spirit of Bash, numerical overflow is silently ignored.)
Because if we can get carrying, borrowing, place value, and the distributive
law right, then the sky's the limit! As they say--erm, as they ___said___ in Rome,
Ad astra per aspera.
## And now...
You can run your floating-point calculations directly in Bash!
## Please see also:
[A short discussion on arbitrary precision and shellmath](https://github.com/clarity20/shellmath/wiki/Shellmath-and-arbitrary-precision-arithmetic)
bash-5.2的源代码,纯C的shell
需积分: 0 97 浏览量
更新于2023-01-20
收藏 10.44MB GZ 举报
**正文**
bash-5.2源代码的分析与学习,是深入理解Linux系统及命令行交互的核心内容。作为Linux中最常用的Shell,Bash(Bourne-Again SHell)不仅是一个用户界面,也是脚本编程的强大工具。它以其灵活性、可扩展性和广泛的功能集,在系统管理和自动化任务中扮演着关键角色。
我们要明确Bash是用C语言编写的,这意味着我们可以从源代码中学习到C语言在实现复杂系统级别的应用时如何组织和管理代码。C语言的特性使得Bash能够高效地执行命令,同时保持与其他系统组件的紧密集成。
在源代码中,我们可以看到以下几个重要的组成部分:
1. **解析器(Parser)**:这部分代码负责将用户输入的命令行字符串转换为内部可以处理的数据结构。它涉及到词法分析和语法分析,包括识别命令、参数、管道、重定向等元素。
2. **命令执行器(Command Executor)**:这部分代码负责根据解析后的数据结构执行命令。它处理子进程的创建、环境变量的设置、信号处理以及错误处理等。
3. **历史记录(History)**:Bash支持命令历史功能,源代码中包含了保存和检索用户输入历史记录的实现。这涉及到动态内存管理、文件操作和用户交互。
4. **扩展和函数(Extensions and Functions)**:Bash提供了许多内置命令和功能,如别名、函数、数组、流程控制等。这些扩展在源代码中以独立模块存在,可以深入了解其工作原理。
5. **脚本解释器(Script Interpreter)**:Bash能读取并执行脚本文件,源代码展示了如何处理脚本中的控制结构(如if-else、for、while循环)、函数定义、条件表达式等。
6. **信号处理(Signal Handling)**:Bash对信号的响应是其可靠性的重要部分,源代码揭示了如何注册信号处理函数和处理不同类型的系统信号。
通过研究bash-5.2的源代码,开发者可以学到如何设计一个健壮的命令行解释器,如何高效地处理I/O重定向和管道,以及如何在多进程环境中协调工作。这对于理解操作系统的工作机制、提高系统编程技能以及编写自己的Shell或者脚本工具都有极大的帮助。
此外,Bash源代码中还包含了丰富的错误检查和调试信息,这对理解程序在遇到问题时如何进行自我诊断至关重要。对于那些希望为Bash贡献代码或自定义功能的开发者来说,深入阅读和理解源代码是必不可少的步骤。
总而言之,bash-5.2的源代码是一个深入学习Linux Shell、C语言编程、命令行交互和系统级编程的宝贵资源。通过仔细研究,我们可以提升对操作系统底层运作的理解,提高编程能力,并且掌握更多自动化工具的实现细节。
懵想的学子
- 粉丝: 3
- 资源: 3
最新资源
- TMS320F28069控制500-1000Vdc 0-60A 30KW 三相PFC充电桩程序
- 双馈风机 DFIG 低电压穿越 MATLAB仿真模型 LVRT 双馈异步风力 Crowbar电路 (1)转子侧变器采用基于定子电压定向的矢量控制策略,有功无功解耦,具备MPPT能力,采用功率外环电
- 电机控制器,FPGA 硬件电流环 基于FPGA的永磁同步伺服控制系统的设计,在FPGA实现了伺服电机的矢量控制 有坐标变,电流环,速度环,位置环,电机反馈接口,SVPWM Verilog
- 鲁棒优化多阶段规划 利用列和约束生成(C&CG)算法进行求解 提升了配电网对可再生能源的消纳能力且改善了配电网的运行指标,同时又保证了微电网投资商的经济利益,有效实现了配电网与微电网的协调发展
- 脉振方波HFI HFI脉振方波高频注入模型代码和matlab仿真 码基于TI283x,:::仿真和相关文档齐全,有仿真的代码,仿真也可以生成代码
- 主机欧姆龙CP1H,主机带四轴,从机CP1H带数轴进行运动控制 全自动CE锂电极片多极耳连续冲切机 欧姆龙CP1H+MCGS昆仑通态触摸屏 伺服电机控制,电阻尺应用控制,电芯极耳间距定长冲切控制,涵盖
- 物流中心选址规划 帝企鹅优化调度算法 基于帝企鹅优化算法的全国物流中心选址规划算法MATLAB程序源代码及完整数据表格(Excel文件,详见附图) 程序到手可运行 关联词:备选点选址规划,调度
- 风机变桨控制FAST与MATLAB SIMULINK联合仿真模型非线性风力发电机的 PID独立变桨和统一变桨控制下仿真模型,对于5WM非线性风机风机进行控制 链接simulink的scope出转速对比
- 逆变器光伏并网逆变器资料,包含原理图,pcb,源码以及元器件明细表 如下: 1) 功率接口板原理图和pcb,元器件明细表 2) 主控DSP板原理图(pdf);如果有需要,可发mentor版
- PSASP环境下基于PMU同步测量的分区惯量估计方法,附资料 对应主要模式下的频率、分区联络线功率测量,做为PMU计算的依据: 1、恒功率负荷模式; 2、感应电动机负荷模式; 3、1模式基础上叠加2
- TMS320F28069控制500-1000Vdc 0-60A 30KW 三相PFC充电桩硬件设计
- 基于simulink的FCV燃料电池电动汽车模型 包含3个汽车模型,双输入DCDC模型,电池管理系统模型 模型建模清晰,运行良好,部分内容如截图所示 需要matlab2015b
- 基于Html与C#、CSS、JavaScript的Blazor入门课程设计源码
- 西门子1500PLC大型立体仓库堆垛机输送机程序项目,具体为智能物流实际项目案例,成熟并且稳定的运行现场,有一万多个库位,输送机一百多个,堆垛机八个,仓库分楼下和楼上两层,以西门子1500plc为控制
- 24V 65W 120W 350W反激电源 全套资料(原理图+PCB+变压器规格+测试报告)
- PMSM模型预测电流控制集(MPCC):单矢量,双矢量,三矢量;单步预测,两步预测,三步预测;两点平,三电平;无差拿预测...... 仿真模型和文档包括且不限于:见图