gav*_*koa 5 bash shell posix cross-platform sh
根据 POSIX:
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html
在某些情况下,它并不明显。例如:
If the file is not in the current working directory,
the implementation may perform a search for an executable
file using the value of PATH, as described in Command Search and Execution.
Run Code Online (Sandbox Code Playgroud)
我的 Bash 4.x 没有遵循这个可选规则(出于安全考虑??)所以我无法测试它在现实生活中的情况......
在shell脚本中查找shell可执行文件目录的平台独立方式是什么?
附注。此外dirname $0
案例失败:
#!/bin/sh
echo $0
dirname $0
Run Code Online (Sandbox Code Playgroud)
当你:
$ sh runme.sh
runme.sh
.
Run Code Online (Sandbox Code Playgroud)
所以你需要这样的东西:
CMDPATH=`cd $(dirname $0); echo $PWD`
Run Code Online (Sandbox Code Playgroud)
为了使代码仅依赖于内置 shell 功能,我将代码重写为:
PREVPWD=$PWD
cd ${0%${0##*/}}.
CMDPATH=$PWD
cd $PREVPWD
Run Code Online (Sandbox Code Playgroud)
这看起来很丑,但不需要 fork 任何可执行文件......
编辑3:
虽然还不是严格的 POSIX,但realpath是自 2012 年以来的 GNU 核心应用程序。完全披露:在我在info coreutils
TOC 中注意到它并立即想到这个问题之前从未听说过它,但是使用如下所示的函数应该可靠,(很快 POSIXLY?),并且,我希望,有效地为其调用者提供一个绝对来源$0
:
% _abs_0() {
> o1="${1%%/*}"; ${o1:="${1}"}; ${o1:=`realpath -s "${1}"`}; eval "$1=\${o1}";
> }
% _abs_0 ${abs0:="${0}"} ; printf %s\\n "${abs0}"
/no/more/dots/in/your/path2.sh
Run Code Online (Sandbox Code Playgroud)
EDIT4:值得强调的是,该解决方案使用POSIX 参数扩展首先检查路径是否确实需要扩展和解析,然后再尝试这样做。这应该返回一个绝对来源$0
的信使变量 (有一个显着的例外,-s
将保留symlinks
),就像我想象的那样有效,无论路径是否已经是绝对的。
编辑2:
现在我相信我更了解您的问题,不幸的是,这实际上使以下大部分内容无关紧要。
(小编辑:在realpath
文档中找到之前,我至少减少了我的版本不依赖于时间字段,但是,公平的警告,在测试了一些之后我不太相信ps
它的命令路径扩展能力是完全可靠的)
另一方面,你可以这样做:
ps ww -fp $$ | grep -Eo '/[^:]*'"${0#*/}"
eval "abs0=${`ps ww -fp $$ | grep -Eo ' /'`#?}"
Run Code Online (Sandbox Code Playgroud)
我需要修复它以更好地与字段一起工作,而不是期望时间字段恰好在进程路径之前出现并依赖其包含的冒号作为参考,特别是因为这不适用于进程路径中的冒号,但这是微不足道的我想很快就会发生。我相信该功能在其他方面符合 POSIX 标准。我认为,可能仅参数扩展就可以做必要的事情。
不严格相关(或正确):
这应该适用于符合 POSIX 准则的每种情况:
echo ${0%/*}
Run Code Online (Sandbox Code Playgroud)
编辑:
所以我承认,至少乍一看,我并不完全理解你所描述的问题。显然,在您的问题中,您展示了对通过参数扩展进行变量字符串操作的 POSIX 标准的一些熟悉程度(即使您的特定实现乍一看似乎有些紧张),因此在我对您的问题的解释中,我可能遗漏了一些重要信息也许,至少就目前的形式而言,这不是您寻求的答案。
我之前已经发布过关于内联变量 null/set 测试的参数扩展,这些测试可能对您有用,也可能没用,正如您在“检查外壳变量的空性的便携式方法”问题中所见。我提到这一点主要是因为我的答案大部分是从 POSIX 参数扩展指南中复制/粘贴的,包括一个锚定链接该主题指南覆盖范围,以及来自规范文档和我自己的一些示例,可能不太专业演示的构造。
然而,我可以坦率地承认,虽然我还没有完全理解你问的是什么,但我不相信你会在那里找到具体的答案。相反,我怀疑您可能忘记了,就像我偶尔做的那样,POSIX 字符串操作中的#
and%
运算符用于指定要删除的字符串部分,而不是您希望保留的部分,因为有些人可能会觉得更直观。我的意思是,您以这种方式搜索的任何字符串切片都被设计为从您的输出中消失,然后在您指定的搜索字符串被删除后,这将只是您原始字符串的剩余部分。
所以这里有一些概述:
而任一运算符的单个实例将只删除尽可能少的内容以完全满足您的搜索,但是当双实例化时,搜索将以贪婪的形式调用并删除您的搜索可能允许的尽可能多的原始字符串。
除此之外,您只需要了解一些基本的正则表达式,并记住从左侧#
开始搜索删除字符串并向右扫描,然后从右侧开始搜索并向左扫描。%
## short example before better learning if I'm on the right track
## demonstrating path manipulation with '#' and '%'
% _path_one='/one/two/three/four.five'
% _path_two='./four.five'
## short searching from the right with our wildcard to the right
## side of a single character removes everything to the right of
## of the specified character and the character itself
## this is a very simple means of stripping extensions and paths
% echo ${_path_one%.*} ${_path_one%/*}
/one/two/three/four /one/two/three
## long searching from the left with the wildcard to the left of
## course produces opposite results
% echo ${_path_one##*.} ${_path_one##*/}
five four.five
## will soon come back to show more probably
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1077 次 |
最近记录: |