加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

bash – 在shell脚本中查找shell可执行文件目录的独立平台方式是

发布时间:2020-12-15 21:09:38 所属栏目:安全 来源:网络整理
导读:根据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 executablefile using the value of PATH
根据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.

我的Bash 4.x不遵循这个可选规则(由于安全问题??)所以我无法测试它在现实生活中的情况……

什么平台独立的方式在shell脚本中查找shell可执行文件的目录?

PS. dirname $0的情况也失败了:

#!/bin/sh
echo $0
dirname $0

当你:

$sh runme.sh
runme.sh
.

所以你需要这样的东西:

CMDPATH=`cd $(dirname $0); echo $PWD`

为了使代码仅依赖于内置shell功能,我将代码重写为:

PREVPWD=$PWD
cd ${0%${0##*/}}.
CMDPATH=$PWD
cd $PREVPWD

这看起来很难看但不需要fork任何可执行文件……

解决方法

EDIT3:

虽然不是严格的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 %sn "${abs0}"
/no/more/dots/in/your/path2.sh

编辑4:值得强调的是,该解决方案使用POSIX parameter expansion首先检查路径是否实际需要扩展和解析,然后再尝试这样做.这应该返回一个绝对来源的$0通过一个messenger变量(有一个值得注意的例外–s将保留符号链接),就像我想象的那样,无论路径是否已经是绝对的,都可以完成.

EDIT2:

现在我相信我理解你的问题要好得多,不幸的是,这实际上使下面的大部分内容无关紧要.

(次要编辑:在文档中找到realpath之前,我至少减少了我的版本,不依赖于时间字段,但是,公平警告,在测试之后我不太相信ps在其命令路径中是完全可靠的扩展能力)

另一方面,你可以这样做:

ps ww -fp $$| grep -Eo '/[^:]*'"${0#*/}"

eval "abs0=${`ps ww -fp $$| grep -Eo ' /'`#?}"

我需要修复它以更好地使用字段而不是期望时间字段在进程的路径之前并依赖于其包含的冒号作为引用,特别是因为这不适用于进程路径中的冒号,但这是微不足道的我想很快就会发生.我相信,该功能符合POSIX标准.我认为可能只有参数扩展可以做必要的事情.

不严格相关(或正确):

这应该适用于符合POSIX指南的每种情况:

echo ${0%/*}

编辑:

所以我承认,至少乍一看,我并不完全理解你描述的问题.显然在您的问题中,您通过参数扩展展示了对变量字符串操作的POSIX标准的熟悉程度(即使您的特定实现看起来有点紧张),所以在我对您的问题的解释中,我可能会遗漏一些重要的信息也许,至少在目前的形式下,这不是你寻求的答案.

我之前已经发布了内联变量null / set测试的参数扩展,这可能会对您有用,也可能没有用,正如您在“Portable Way to Check Emptiness of a Shell Variable”问题中看到的那样.我之所以提到这一点,主要是因为我的答案大部分是从POSIX指南中复制/粘贴参数扩展,包括anchored link关于这个主题的指南报道,以及来自规范文档的一些例子和我自己可能不太专业的证明结构体.

但我会坦然承认,虽然我还没有完全明白你问的是什么,但我不相信你会在那里找到具体的答案.相反,我怀疑你可能已经忘记了,我偶尔也会忘记POSIX字符串操作中的#和%运算符用于指定要删除的字符串部分,而不是您希望保留的部分可能会更直观.我的意思是你以这种方式搜索的任何字符串切片都被设计为从输出中消失,然后这将只是删除指定搜索字符串后原始字符串的剩余部分.

所以这里有一点概述:

尽管任一运算符的单个实例将尽可能少地删除以完全满足您的搜索,但是当双重实例化时,搜索以贪婪的形式被调用并且移除尽可能多的原始字符串,因为您的搜索可能允许.

除此之外,你只需要知道一些基本的正则表达式并记住#开始从左边搜索你的删除字符串并向右扫描,而%%开始从右边搜索它并向左扫描.

## 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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读