我总是在命令之后写 stdin 重定向,因为对我来说,首先命令然后重定向(如果有)更自然:
some-command < input-file > output-file
Run Code Online (Sandbox Code Playgroud)
多年来,我看到人们在命令之前编写 stdin 重定向,以获得一些流程方向:
< input-file some-command > output-file (or without spaces after < and > )
Run Code Online (Sandbox Code Playgroud)
这个顺序是被 POSIX 接受还是被许多 shell 接受(在我的 Fedora 21 中,它被bash
, dash
, tcsh
,ksh
和接受zsh
)?
在编写一些代码时,我发现这一行:
$ TZ="America/Los_Angeles" date; echo "$TZ"
Thu Dec 24 14:39:15 PST 2015
Run Code Online (Sandbox Code Playgroud)
正确给出“洛杉矶”的实际时间,并且TZ
不保留变量的值。一切都在意料之中。
但是,使用这一行,我曾经扩展了一些格式,并且基本上执行了相同的操作,保留了 TZ 的值:
TZ="America/Los_Angeles" eval date; echo "$TZ"
Thu Dec 24 14:41:34 PST 2015
America/Los_Angeles
Run Code Online (Sandbox Code Playgroud)
经过多次测试,我发现这种情况只发生在某些 shell 中。它发生在 dash、ksh 中,但不发生在 bash 或 zsh 中。
问题是:
我用这两行在几个 shell 中运行了测试:
myTZ="America/Los_Angeles"
unset TZ; { TZ="$myTZ" date; } >/dev/null; echo -n " direct $TZ"
unset TZ; { TZ="$myTZ" eval date; } >/dev/null; echo " evaled $TZ"
Run Code Online (Sandbox Code Playgroud)
结果如下:
/bin/ash : direct evaled America/Los_Angeles
/bin/dash : …
Run Code Online (Sandbox Code Playgroud) 找出有关文件的文件系统信息的最佳方法是什么。
例如,如果我有一个文件
/media/xyz/path/to/file.ext
Run Code Online (Sandbox Code Playgroud)
并/etc/fstab
包含
//server1/Share1 /media/xyz cifs option1=value1,...
Run Code Online (Sandbox Code Playgroud)
我如何确定文件是否在 Samba 共享上,它具有本地路径/path/to/file.ext
以及文件系统安装的选项?
正在解析mount
便携式解决方案的输出吗?还是解析findmnt
?是否有符合 POSIX 标准的方法来实现这一目标?
我知道有些 shell 接受这种测试:
t() { [[ $var == *$'\n'* ]] && res=yes || res=no
printf '%s ' "$res";
}
var='ab
cd'
t
var='abcd'
t
echo
Run Code Online (Sandbox Code Playgroud)
执行时:
$ bash ./script
yes no
Run Code Online (Sandbox Code Playgroud)
什么是 POSIX(破折号)工作等效项
以下是可靠的测试方法吗?
nl='
'
t() { case "$var" in
*$nl* ) res=yes ;;
* ) res=no ;;
esac
printf '%s ' "$res"
}
var='ab
cd'
t
var='abcd'
t
echo
Run Code Online (Sandbox Code Playgroud)支撑扩展,例如 {a,b,c}不是由 POSIX 定义的。我想在 POSIX 模式下运行我的 shell。使用 Debian 这很简单:
$ bash -c 'echo {a,b,c}'
a b c
$ sh -c 'echo {a,b,c}'
{a,b,c}
Run Code Online (Sandbox Code Playgroud)
但是 Fedora 的行为有所不同:
$ bash -c 'echo {a,b,c}'
a b c
$ sh -c 'echo {a,b,c}'
a b c
Run Code Online (Sandbox Code Playgroud)
我尝试使用--posix
选项,但没有效果:
$ sh --posix -c 'echo {a,b,c}'
a b c
Run Code Online (Sandbox Code Playgroud)
Bash 可以强制在 POSIX 模式下运行吗?
在 BSD sed 上,-E
是“扩展正则表达式”标志。在 GNU sed 上,文档指出这-r
是扩展的正则表达式标志,但-E
开关也能正常工作(尽管在我的研究中没有记录)。
我记得读过-E
将在下一版 POSIX 规范中指定的某个地方,但我找不到我在哪里读到的。
(这是真的吗?是否有权威参考,或者这里的用户是权威?)
究竟有多便携是在-E
为开关sed
?
是否有标准(即POSIX兼容)的版本sed
上-E
是不支持?(哪个?)
为什么-E
没有为 GNU sed 记录该标志?
只有read -r
是通过POSIX规定; read -n NUM
,用于读取NUM
字符,不是。从标准输入读取给定数量的字符后,是否有一种可移植的方式自动返回?
我的用例正在打印这样的提示:
Do the thing? [y/n]
Run Code Online (Sandbox Code Playgroud)
如果可能,我希望程序在键入后自动运行y
或n
,而无需用户随后按 Enter 键。
我知道 dash 非常严格地遵守 POSIX 标准,但我知道它不是 100.00% 严格的 POSIX,没有任何额外的东西。据我所知,最接近/完全遵守 POSIX 标准的 shell 是设置了 POSIXly 正确标志的 mrsh 或 yash。
现在我想确切地知道 POSIX 标准中没有指定 dash 的哪些部分/功能(无需阅读整个POSIX.1-2017和 dash 的源代码)。
我已经尝试过广泛的谷歌搜索(就我对这个主题的了解而言),但谁会想到,这完全是关于 bash 和 dash 之间的差异以及 dash 如何非常符合 POSIX 等等的结果。
我想使用2.6.2 参数扩展从字符串中删除前导字符,但惊讶地发现“删除最大前缀模式”不会自动重复该模式。
$ x=aaaaabc
$ printf %s\\n "${x##a}"
aaaabc
Run Code Online (Sandbox Code Playgroud)
如您所见,只有第一个a
已被删除。预期输出为、、或中bc
的任何一个。x=bc
x=abc
x=aabc
x=aaabc
x=aaaabc
a
如果我想从 的开头删除尽可能多的内容,我正在努力弄清楚如何编写该模式$x
。我也没有运气搜索其他线程,因为许多答案都使用 bash,但我正在寻找 POSIX shell 解决方案。