posix shell expansion,non-interactiveshell模仿interactive,命名管道fifo

摘要

posix shell 判断变量是否存在 使用所有shell sh bash zsh fish

subprocess popen 交互式 shell interactive shell

posix shell 判断变量是否存在 使用所有shell sh bash zsh fish

代码

例子中, PYTHONPATH不存在但是PATH存在.

ver 1

$ if [ -z ${PYTHONPATH:+exist_and_not_empty} ]; then return 1; else return 0; fi
$ echo $?
1
$ if [ -z ${PATH:+exist_and_not_empty} ]; then return 1; else return 0; fi
$ echo $?
0

ver 2

$ echo ${PATH:?not_exist_or_empty}
# ...
$ echo $?
0
$ echo ${PYTHONPATH:?not_exist_or_empty}
zsh: PYTHONPATH: not_exist_or_empty
$ echo $?
1

原理

参考 stackoverflow.com/a/16753536

+--------------------+----------------------+-----------------+-----------------+
|   Expression       |       parameter      |     parameter   |    parameter    |
|   in script:       |   Set and Not Null   |   Set But Null  |      Unset      |
+--------------------+----------------------+-----------------+-----------------+
| ${parameter:-word} | substitute parameter | substitute word | substitute word |
| ${parameter-word}  | substitute parameter | substitute null | substitute word |
| ${parameter:=word} | substitute parameter | assign word     | assign word     |
| ${parameter=word}  | substitute parameter | substitute null | assign word     |
| ${parameter:?word} | substitute parameter | error, exit     | error, exit     |
| ${parameter?word}  | substitute parameter | substitute null | error, exit     |
| ${parameter:+word} | substitute word      | substitute null | substitute null |
| ${parameter+word}  | substitute word      | substitute word | substitute null |
+--------------------+----------------------+-----------------+-----------------+


+--------------------+----------------------+-----------------+-----------------+
|   Expression       |  When FOO="world"    |  When FOO=""    |    unset FOO    |
|   in script:       |  (Set and Not Null)  |  (Set But Null) |     (Unset)     |
+--------------------+----------------------+-----------------+-----------------+
| ${FOO:-hello}      | world                | hello           | hello           |
| ${FOO-hello}       | world                | ""              | hello           |
| ${FOO:=hello}      | world                | FOO=hello       | FOO=hello       |
| ${FOO=hello}       | world                | ""              | FOO=hello       |
| ${FOO:?hello}      | world                | error, exit     | error, exit     |
| ${FOO?hello}       | world                | ""              | error, exit     |
| ${FOO:+hello}      | hello                | ""              | ""              |
| ${FOO+hello}       | hello                | hello           | ""              |
+--------------------+----------------------+-----------------+-----------------+

subprocess popen 交互式 shell interactive shell

subprocess

如果 p = Popen(…)

p.communicate 无法交互式运行! 只要cmd执行完, 整个进程都结束了!

p.stdin.write p.stdout.read p.wait 也无法交互式运行! wait导致整个进程都结束了!

实际上 p.communicate = p.stdin.write p.stdout.read p.wait

sh只能执行固定数量的shell命令. 但是, 终端的交互式shell是怎样实现的呢? 请看!

$ while true
> do read line
> $line
> done

怎样写成一行呢?

while true do read line $line done # 大错特错!

sh报错: 没有do

可是我们明明写了do?

while true; do read line; $line; done; # 😀👍

原来do也类似一条命令! 要么以;结尾要么以\n结尾!

sh中大致有三种命令

  • 外存二进制镜像/解释器及脚本 which ls/usr/bin/ls
  • 内置命令 which cdcd: shell built-in command
  • 保留关键字 which esacesac: shell reserved word

esac这种碳基生物整不出的活儿,竟然是为了防止保留字吃掉我们的变量名,他真的我哭死…😵

do是一条命令 要么以;结尾要么以\n结尾 $line可以看作do的参数
do是一条命令 要么以;结尾要么以\n结尾 $line可以看作do的参数
do是一条命令 要么以;结尾要么以\n结尾 $line可以看作do的参数

# leaf @ machine in ~ [16:33:52]
$ mkfifo p q

# leaf @ machine in ~ [16:34:02]
$ sh -c 'while true; do read line && $line; done;' < p > q &
[1] 299

# leaf @ machine in ~ [16:34:09]
$ cat q &
[2] 308

# leaf @ machine in ~ [16:34:17]
$  echo 'pwd' > p
/home/leaf

# leaf @ machine in ~ [16:34:24]
$ echo 'ls' > p
bin
mine
p
q

为什么要手动构造管道呢? 因为默认构造的subprocess.PIPE是unnamed pipe

在这里插入图片描述

# leaf @ machine in ~ [16:47:34]
$ bash -c 'n=0; while (($n<=3)); do echo $n; n=$((n+1)); sleep 1; done;' | dd
0
1
2
3
0+4 records in
0+1 records out
8 bytes copied, 4.00424 s, 0.0 kB/s

注意 4.00424 s 这说明匿名管道 写端完成 读端才可读 因此 subprocess.PIPE 无法实现交互式命令!

⚠ & 和 ; 都是shell的结束符, 二者至多出现一个.
如果两个结束符之间为空, bash和zsh可能不报错, 但是/bin/sh会报错!

sh -c 'while true; do read line && $line; done;' < p > q & ; ×

sh -c 'while true; do read line && $line; done;' < p > q &

怎样处理异步通信的问题呢?比方说 sleep 1 ;这就是操作系统、分布式系统的内容了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
POSIX(Portable Operating System Interface)是一种操作系统接口标准,旨在促进不同的操作系统之间的软件可移植性和互操作性。POSIX标准主要由IEEE制定,它定义了一系列的API(应用程序接口)和工具,包括C语言函数库、命令行工具和Shell语言。 在Shell编程中,POSIX Shell标准是一种符合POSIX规范的Shell语言。它提供了一组可移植且通用的Shell命令和语法,使得Shell脚本能够在不同的POSIX兼容操作系统上运行。POSIX Shell标准的主要目的是确保Shell脚本的可移植性和可靠性。 POSIX Shell标准包含了很多常用的Shell命令,如cd、ls、rm等,以及控制流语句、变量和环境等。使用这些命令和语法,开发者可以编写能够在不同的POSIX兼容系统上正常工作的Shell脚本。另外,POSIX Shell标准还定义了一些特殊的变量和内置命令,如$IFS和echo等。 遵循POSIX Shell标准的好处是,可以确保自己的Shell脚本能够在各种POSIX兼容的操作系统上顺利运行,无需根据不同操作系统的特定要求进行调整。这样,开发者可以更高效地编写和维护跨平台的Shell脚本。 总之,POSIX Shell标准是一种符合POSIX规范的Shell语言,它提供了一组可移植且通用的Shell命令和语法,确保Shell脚本在不同的POSIX兼容操作系统上正常运行。遵循POSIX Shell标准可以提高脚本的可移植性和可靠性,更好地适应不同的操作系统环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值