如果 Unix (Posix) 进程接收到信号,信号处理程序将运行。
在多线程进程中它会发生什么?哪个线程接收信号?
在我看来,信号 API 应该被扩展来处理(即信号处理程序的线程应该能够被确定),但是在网上寻找信息我只在 linux 内核邮件列表和上发现了长达一年的火焰不同的论坛。据我了解,Linus 的概念不同于 Posix 标准,首先构建了一些兼容层,但现在 Linux 遵循 posix 模型。
目前的状态是什么?
我的公司转售了一个应用程序,其品牌名称是大小写混合的,例如“ApplicationName”。
应用程序的安装程序在此标准中创建所有路径和文件名。例如,主目录是/opt/ApplicationName,调用了 init 文件,ApplicationName所以我必须运行service ApplicationName status等等。
对我来说,这打破了所有合理的约定,我觉得文件和目录都应该是小写的(在其他应用程序如 MySQL 中有先例,其文件和目录都被称为 mysql,甚至 Apache 和 Tomcat 之类的应用程序也取消了前面的大写字母)。
如果我将此作为错误报告提出,我想提出一个更有力的论据,而不仅仅是“我认为这是错误的”。那么像 POSIX 标准这样的系统文件是否应该是小写的呢?
我正在尝试shellcheck。
我有类似的东西
basename "${OPENSSL}"
Run Code Online (Sandbox Code Playgroud)
我得到以下建议
Use parameter expansion instead, such as ${var##*/}.
Run Code Online (Sandbox Code Playgroud)
从实际的角度来看,我认为没有区别
$ export OPENSSL=/opt/local/bin/openssl
$ basename ${OPENSSL}
openssl
$ echo ${OPENSSL##*/}
openssl
Run Code Online (Sandbox Code Playgroud)
由于basename在POSIX 规范中,我不知道为什么它应该是最佳实践。任何提示?
POSIX 将文本文件定义为:
包含组织成零个或多个行的字符的文件。这些行不包含 NUL 字符,并且长度不能超过 {LINE_MAX} 个字节,包括 <newline> 字符。尽管 POSIX.1-2017 不区分文本文件和二进制文件(参见 ISO C 标准),但许多实用程序仅在对文本文件进行操作时产生可预测或有意义的输出。具有此类限制的标准实用程序总是在其 STDIN 或 INPUT FILES 部分中指定“文本文件”。
来源:http : //pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_403
但是,有几件事我觉得不清楚:
文本文件必须是普通文件吗?在上面的摘录中没有明确说明文件必须是常规文件
如果文件只包含一个字符和一个字符(即不以换行符结尾的单个字符),是否可以将文件视为文本文件?我知道这个问题可能听起来很挑剔,但他们使用“字符”一词而不是“一个或多个字符”。其他人可能不同意,但如果他们的意思是“一个或多个字符”,我认为他们应该明确地说出来
在上面的摘录中,它提到了“线条”。我发现了四个名称中带有 line 的定义:“Empty Line”、“Display Line”、“Incomplete Line”和“Line”。我是否应该推断它们的意思是“线”,因为它们省略了“空”、“显示”和“不完整”——或者所有这四个定义都被认为是上面摘录中的一条线?
此文本块之后出现的所有问题都取决于推断“字符”表示“一个或多个字符”:
此文本块之后的所有问题都取决于推断,在上面的摘录中,一行被定义为“行”,并且应排除名称中包含“行”的其他三个定义:
“零行或多行”中的“零”是否意味着如果文件包含一个或多个未以换行符终止的字符,则仍可将其视为文本文件?
“零行或多行”是否意味着一旦单个“行”(0 个或多个字符加上终止换行符)开始发挥作用,最后一行成为“不完整行”(一个或多个非文件末尾的换行符)?
“无 [无行] 的长度可以超过 {LINE_MAX} 个字节,包括换行符”是否意味着文本文件中任何给定“行”中允许的字符数有限制(顺便说一句, Ubuntu 18.04 和 FreeBSD 11.1 上的 LINE_MAX 是“2048”)?
我经常想获得与用户 ID 关联的登录名,并且因为它被证明是一个常见的用例,所以我决定编写一个 shell 函数来做到这一点。虽然我主要使用 GNU/Linux 发行版,但我尝试将脚本编写为尽可能可移植,并检查我所做的是否与 POSIX 兼容。
/etc/passwd我尝试的第一种方法是解析/etc/passwd(使用awk)。
awk -v uid="$uid" -F: '$3 == uid {print $1}' /etc/passwd
Run Code Online (Sandbox Code Playgroud)
但是,这种方法的问题在于登录可能不是本地的,例如,用户身份验证可能通过 NIS 或 LDAP。
getent命令使用getent passwd比解析更具可移植性,/etc/passwd因为它还可以查询非本地 NIS 或 LDAP 数据库。
getent passwd "$uid" | cut -d: -f1
Run Code Online (Sandbox Code Playgroud)
不幸的是,该getent实用程序似乎并未由 POSIX 指定。
id命令id 是 POSIX 标准化实用程序,用于获取有关用户身份的数据。
BSD 和 GNU 实现接受用户 ID 作为操作数:
如果 shell 被要求执行一个已知会终止的可能无用(或部分无用)的命令,例如cat hugeregularfile.txt > /dev/null,它是否可以跳过该命令的执行(或执行更便宜的等价物,例如, touch -a hugeregularfile.txt)?
更一般地说,shell 是否类似于 C 编译器,因为它可以对源代码执行任何转换,只要外部可观察的行为就像抽象机器评估它一样?
编辑
Nota Bene:我最初提出的问题有一个标题,询问是否允许shell进行这些优化,而不是是否应该甚至是否存在可以执行这些优化的实现。我对理论比实践更感兴趣,尽管两者都是受欢迎的。
所以我一直在 linux 上使用 'sed' 一段时间,但是在尝试在 OSX 上使用它时遇到了一些困难,因为 'POSIX sed' 和 'GNU sed' 有很多细微的差别。目前我正在努力解决如何在某个行号后插入一行文本。(在本例中,第 4 行)
在 linux 上,我会做这样的事情:
sed --in-place "4 a\ mode '0755'" file.txt
Run Code Online (Sandbox Code Playgroud)
所以在 OSX 上我试过这个:
sed -i "" "4 a\ mode '0755'" file.txt
Run Code Online (Sandbox Code Playgroud)
但是,这一直给我一个“命令末尾\ 后的额外字符”错误。任何想法这里有什么问题?我有错别字吗?还是我不明白 sed 版本之间的另一个区别?
几年来,除非使用选项调用GNUrm实用程序,/否则它不会删除--no-preserve-root。然而,这个命令rm -rf /在很长一段时间内都被认为是危险的集体潜意识,人们仍然经常将其称为“可怕”的命令。
我想知道这个rm不能删除的规则是什么时候/出现的。我检查了 POSIX 规范,我可以看到,虽然POSIX:2008包含此安全功能,但POSIX:2001没有。由于POSIX规范的在线版本不时更新,随着每个新的子发布,我也检查了回程机,找到了2010年的POSIX:2008的相关页面,并能够确认rm无法删除的规则/当时已经上市了。
所以,我的问题是:
rm不能删除的规则是什么时候/添加到 POSIX 规范中的?它是在单一 UNIX 规范第 4 版的原始 2008 版中还是在修订版中添加的?rm什么时候添加到 GNU 的?我很确定它是在它被添加到 POSIX 之前,但它是什么时候发生的?在 C 中,运行标准实用程序(例如 ps)而不是其他的最简单方法是什么?
例如,POSIX 是否保证存在标准ps,/bin/ps或者我应该将 PATH 环境变量重置为我所获得的值confstr(_CS_PATH, pathbuf, n);,然后通过 PATH-search 运行该实用程序?
我有以下代码,它是source我的-d.shellrc
PATH="${PATH}:${HOME}/perl5/bin"
PATH="${PATH}:${HOME}/.bin"
export PATH
Run Code Online (Sandbox Code Playgroud)
但是,如果我更改其他代码然后更改source此文件,则每个源的路径都会越来越长,每次都在它们已经存在时追加。我能做些什么来防止这种情况?