当寻找的路径,可执行文件或检查,如果你在Unix shell中输入命令的名称会发生什么,有不同的公用事业过多(which
,type
,command
,whence
,where
,whereis
,whatis
,hash
,等)。
我们经常听说which
应该避免。为什么?我们应该用什么来代替?
只是寻找之间的区别
2>&-
2>/dev/null
|&
&>/dev/null
>/dev/null 2>&1
以及它们与非的Bourne shell喜欢便携性tcsh
,mksh
等等。
在整个 POSIX 规范中,都有规定 ( 1 , 2 , 3 ...) 允许实现/
特别处理以 2 开头的路径。
POSIX 应用程序(根据 POSIX 规范编写的应用程序可移植到所有 POSIX 兼容系统)不能假设//foo/bar
与 相同/foo/bar
(尽管他们可以假设///foo/bar
与 相同/foo/bar
)。
现在那些//foo
特殊对待的 POSIX 系统(历史悠久且仍在维护)是什么?我相信(我现在被证明是错误的)微软为他们的 Unix 变体 (XENIX) 和可能的 Windows POSIX 层推送了 POSIX 条款(有人能证实吗?)。
它被 Cygwin 使用,Cygwin 也是 Microsoft Windows 的类似 POSIX 的层。是否有任何非 Microsoft Windows 系统?开放虚拟机?
在//foo/bar
特殊的系统上,它用于什么?//host/path
用于网络文件系统访问?虚拟文件系统?
某些运行在类 Unix 系统上的应用程序(如果不是系统的 API)是否会//foo/bar
特别处理路径(在它们否则将其/foo/bar
视为文件系统上的路径的上下文中)?
编辑,此后我在奥斯汀组邮件列表上询问了//foo/bar
有关规范中处理起源的问题,并且讨论很有趣(至少从考古学的角度来看)。
这可能与检测操作系统有关,但我特别需要系统上当前使用的 init 系统。
Fedora 15 和 Ubuntu 现在使用 systemd,Ubuntu 过去使用 Upstart(很长时间默认直到 15.04),而其他人使用 System V 的变体。
我有一个应用程序,我正在编写它作为跨平台守护程序。初始化脚本是根据可以在配置时传入的参数动态生成的。
我想做的只是为他们正在使用的特定初始化系统生成脚本。这样,安装脚本可以在没有参数的情况下以 root 身份合理运行,并且守护进程可以自动“安装”。
这是我想出的:
这样做的最佳跨/平台方式是什么?
有点相关,我可以依赖 bash 来支持大多数 *nix 还是依赖于发行版/操作系统?
目标平台:
有哪些可移植 shell 编程的资源?最终的答案是在所有目标平台上进行测试,但这很少实用。
该POSIX /统一UNIX规范是一个开始,但它会告诉你没有什么支持每个实现的程度,也没有什么共同的扩展存在。您可以阅读每个实现的文档,但这非常耗时且不完全准确。
在我看来,理想的格式应该是 POSIX 规范的某种社区注释版本,其中每个功能都按其在不同实现中的支持级别进行注释。有这样的事情吗?或者还有其他有用的资源吗?
例如,有Sven Mascheck 的 shell portability pages,但它只涉及语法元素和一些内置函数,并且只涵盖旧 shell。我正在寻找更全面的资源。
有时,我需要指定标准 IO 流 ( stdin
, stdout
, stderr
)之一的“等效路径” 。因为我 99% 的时间都在使用 Linux,所以我只是/dev/
在准备 get/dev/stdin
等,而这“似乎做对了”。但是,一方面,我一直对这样的理由感到不安(因为,当然,“它似乎有效”,直到它没有为止)。此外,我对这种操作的便携性没有很好的了解。
所以我有几个问题:
在Linux中的情况下,它是安全(是/否)划上等号stdin
,
stdout
以及stderr
用/dev/stdin
,/dev/stdout
和
/dev/stderr
?
更一般地说,这个等价物是否“足够便携”?
我找不到任何 POSIX 参考。
我正在为我的服务器编写 shell 脚本,这是一个运行 FreeBSD 的共享主机。我还希望能够在运行 Linux 的 PC 上本地测试它们。因此,我试图以可移植的方式编写它们,但sed
我认为没有办法做到这一点。
我的网站的一部分使用生成的静态 HTML 文件,并且此 sed 行在每次重新生成后插入正确的 DOCTYPE:
sed -i '1s/^/<!DOCTYPE html> \n/' ${file_name.html}
Run Code Online (Sandbox Code Playgroud)
它适用sed
于 Linux上的 GNU ,但 FreeBSDsed
期望-i
选项后的第一个参数是备份副本的扩展名。这是它的样子:
sed -i '' '1s/^/<!DOCTYPE html> \n/' ${file_name.html}
Run Code Online (Sandbox Code Playgroud)
但是,GNUsed
反过来又希望表达式紧跟在 之后-i
。(它还需要修复换行符处理,但这里已经回答了)
当然,我可以在脚本的服务器副本中包含此更改,但这会造成混乱,即我使用 VCS 进行版本控制。有没有办法以完全可移植的方式使用 sed 实现这一点?
我知道我可以
$ [ -w /home/durrantm ] && echo "writable"
writable
Run Code Online (Sandbox Code Playgroud)
或者
$ test -w /home/durrantm && echo "writable"
writable
Run Code Online (Sandbox Code Playgroud)
或者
$ [[ -w /home/durrantm ]] && echo "writable"
writable
Run Code Online (Sandbox Code Playgroud)
我喜欢使用第三种语法。它们在所有方面以及所有负面和边缘情况下都等效吗?可移植性是否有任何差异,例如 Ubuntu 上的 bash 和 OS X 上的 bash 或较旧/较新的 bash 版本,例如 4.0 之前/之后,它们是否都以相同的方式扩展表达式?
(zsh) 脚本确定其绝对路径的可移植方式是什么?
在 Linux 上,我使用类似的东西
mypath=$(readlink -f $0)
Run Code Online (Sandbox Code Playgroud)
...但这不是便携式的。(例如,readlink
在 darwin 上不识别该-f
标志,也没有任何等效项。)(此外readlink
,诚然,使用此方法是一种非常不起眼的 hack。)
什么是更便携的方式?
我正在写一些关于如何安装某些东西的说明(与 TeX 相关 - 如果你不问,我不会通过提供更多细节来破坏你的一天)并用于sudo
在系统范围内安装。有人评论说,他们不认为这sudo
在所有 Linux(或 Unix)发行版上都可用。
是否有没有没有的 Unix 发行版,如果有sudo
,它们是什么?是否有一个举世公认的“给我超级用户权限”命令,该命令是在所有系统上?