我可以写
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
Run Code Online (Sandbox Code Playgroud)
最终结果对我来说似乎都差不多。我为什么要写一个或另一个?这些中的任何一个都不是便携式/ POSIX 吗?
我经常看到到处都提到 POSIX,我认为它是 UNIX 的基线标准……直到我在维基百科页面上注意到以下摘录:The Open Group
由The Open Group是最有名的认证机构为UNIX商标,其公布统一UNIX规范技术标准,它扩展了POSIX标准,是UNIX系统的官方定义。
如果 UNIX 系统的官方定义是 POSIX 的扩展,那么 POSIX 到底是什么?,,, 它确实似乎是 UNIX 世界的试金石,但我不知道它是如何融入全局的。
我可以bash使用或省略function关键字来定义函数。有什么区别吗?
#!/bin/bash
function foo() {
echo "foo"
}
bar() {
echo "bar"
}
foo
bar
Run Code Online (Sandbox Code Playgroud)
这两个函数调用foo和bar成功,我看不出有什么区别。所以我想知道它是否只是为了提高可读性,或者我遗漏了什么......
顺便说一句,在其他 shell 中,例如dash(在 debian/ubuntu 中/bin/sh符号链接dash)它在使用function关键字时失败。
是否有官方的 POSIX、GNU 或其他指南来说明应该在何处打印进度报告和日志信息(例如“Doing foo; foo done”)?就个人而言,我倾向于将它们写入 stderr,这样我就可以重定向 stdout 并仅获取程序的实际输出。我最近被告知这不是一个好的做法,因为进度报告实际上并不是错误,只有错误消息应该打印到 stderr。
这两个职位都有意义,当然您可以根据您正在做的事情的细节选择一个或另一个,但我想知道是否有一个普遍接受的标准。我无法在 POSIX、GNU 编码标准或任何其他此类广泛接受的最佳实践列表中找到任何特定规则。
我们有一些类似的问题,但它们没有解决这个确切的问题:
何时在 shell 脚本中使用重定向到 stderr:接受的答案表明我倾向于做什么,将程序的最终输出保留在 stdout 上,并将其他任何内容保留在 stderr 上。然而,这只是作为用户的意见提出的,尽管有论据支持。
使用消息应该转到 stderr 还是 stdout?:这是特定于帮助消息的,但引用了 GNU 编码标准。这就是我正在寻找的东西,不仅限于帮助消息。
那么,对于进度报告和其他信息性消息(不是程序实际输出的一部分)应该在哪里打印,是否有任何官方规则?
考虑到 POSIX 是所有 unices 中最接近通用标准的东西,我很想知道是否有专门支持它的 shell。尽管大多数现代 shell 都提供对 POSIX 的支持(并且可以毫无问题地运行 POSIX 兼容脚本),但它们在指出不兼容的功能方面做得不好。
是否有任何仅实现 POSIX 和 POSIX 的外壳程序,它会为任何不兼容的功能抛出错误?
编辑我想澄清一下,我不是要求编写可移植 shell 脚本的一般提示。评论中提到的相关问题已经涵盖了这一点。当我发现bash有一个--posix选项时,我想到了这个问题,但只是发现它只影响一些初始化行为,这并不是我正在寻找的。
正如在这个很好的答案中所提到的,POSIX 系统cd除了内置的 shell 之外还有一个外部二进制文件。在 OS X 10.8 上,它是/usr/bin/cd. 您不能像内置函数那样使用它,cd因为它在更改自己的工作目录后立即退出。它的目的是什么?
有时,我需要指定标准 IO 流 ( stdin, stdout, stderr)之一的“等效路径” 。因为我 99% 的时间都在使用 Linux,所以我只是/dev/在准备 get/dev/stdin等,而这“似乎做对了”。但是,一方面,我一直对这样的理由感到不安(因为,当然,“它似乎有效”,直到它没有为止)。此外,我对这种操作的便携性没有很好的了解。
所以我有几个问题:
在Linux中的情况下,它是安全(是/否)划上等号stdin,
stdout以及stderr用/dev/stdin,/dev/stdout和
/dev/stderr?
更一般地说,这个等价物是否“足够便携”?
我找不到任何 POSIX 参考。
我想知道是否有通过 shebang 行 ( #!)将多个选项传递给可执行文件的通用方法。
我使用 NixOS,在我编写的任何脚本中,shebang 的第一部分通常是/usr/bin/env. 然后我遇到的问题是系统将其后的所有内容解释为单个文件或目录。
例如,假设我想编写一个脚本以bash在 posix 模式下执行。写shebang的天真方式是:
#!/usr/bin/env bash --posix
Run Code Online (Sandbox Code Playgroud)
但是尝试执行生成的脚本会产生以下错误:
/usr/bin/env: ‘bash --posix’: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我知道这篇文章,但我想知道是否有更通用和更清洁的解决方案。
编辑:我知道对于Guile脚本,有一种方法可以实现我想要的,在手册的第 4.3.4 节中记录:
#!/usr/bin/env sh
exec guile -l fact -e '(@ (fac) main)' -s "$0" "$@"
!#
Run Code Online (Sandbox Code Playgroud)
这里的技巧是,第二行(以 开头exec)被解释为代码,sh但是,在#!...!#块中,作为注释,因此被 Guile 解释器忽略。
难道不能将此方法推广到任何解释器吗?
第二次编辑:在玩了一会儿之后,似乎对于可以从中读取输入的解释器,stdin以下方法可以工作:
#!/usr/bin/env sh
sed '1,2d' "$0" | bash --verbose --posix …Run Code Online (Sandbox Code Playgroud) 该表达式.*由 bash 扩展以包括当前和父目录:
$ ls -la
total 2600
drwxrwxrwx 2 terdon terdon 2162688 Sep 10 16:22 .
drwxr-xr-x 142 terdon terdon 491520 Sep 10 15:34 ..
-rw-r--r-- 1 terdon terdon 0 Sep 10 16:22 foo
$ echo .*
. ..
Run Code Online (Sandbox Code Playgroud)
如果我rm -rf .*使用 GNU bash 在我的 Debian 上运行,version 4.2.36(1)-release并且rm从rm (GNU coreutils) 8.13,我会收到以下消息:
$ rm -rf .*
rm: cannot remove directory: `.'
rm: cannot remove directory: `..'
Run Code Online (Sandbox Code Playgroud)
这是 GNU 的东西还是 POSIX?是否有任何 …
POSIX、Single UNIX Specification 和Open Group Base Specifications之间有什么区别?我认为他们的目的是确定操作系统是否是 Unix?