从脚本中找到特定文件

从脚本中找到特定文件

我编写了一个脚本文件,其中一个函数搜索另一个脚本,如果找到,则执行该脚本。

脚本摘录

#!/bin/bash
...
service_status() {
local my_script=`which my-services-check.sh 2>/dev/null`
[[ -z "$my_script" ]] && { echo -n "functionality not available" ; failure ; echo ; return ; }
source $my_script    
}
...

当我which my-services-check.sh 2>/dev/null从终端执行此操作时,它会返回该文件的正确路径。

当我运行该函数时服务状态()(调用脚本时),它找不到该文件($my_script为空)。

which我没有尝试使用typeandcommand但最终得到了相同的结果。

路径问题

然后我从终端和脚本打印出来$PATH,果然它们不一样!从我的脚本执行时,被$PATH设置为安全路径,如以下定义/etc/sudoers

Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin

从航站楼出发

echo $PATH /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin: ...

所以,

  1. 如何从我的脚本中可靠地找到我正在寻找的文件? (不使用,find因为我需要的文件必须位于路径中)?

  2. 从脚本执行时为什么 PATH 设置不同?

答案1

交互式 shell 加载.bashrc,但脚本不加载。如果你的$PATH设置为.bashrc 并且你不导出它,该脚本不会继承您对 的修改$PATH。如果您调用export PATH,脚本应该会看到它。检查export -p导出哪些变量($PATH应该在其中)。还要检查$BASH_ENV哪些可能会覆盖您的$PATH.

理想情况下,$PATH应该在您的 中设置和导出.profile,以便在您登录时加载和设置它,并且从那时起对您运行的所有内容都可见。

一个好的做法是不仅检查文件名是否存在,而且检查它是否是一个正确的文件,[[ -f "$my_script" ]]或者(如果您想将其作为脚本调用而不是获取它)开关-x

答案2

实际上并没有任何保证包含在PATH.你会发现/bin,但其他一切都是可能的或可能的。我的系统上的用户将会有类似的东西$HOME/bin:/usr/local/bin:/bin:/usr/bin。根用户也在/usr/local/sbin:/sbin:/usr/sbin那里。

如果您的文件可能位于多个位置之一,您可以在这些可能的位置搜索它。只需删除此搜索中的整个依赖项PATH,或扩展 PATH 以包含可能找到脚本的最小位置集。

local OPATH="$PATH"
PATH="$PATH:/extra/place:/another/extra/place"
local my_script=$( which my-services-check.sh 2>/dev/null )
PATH="$OPATH" # Restore the original PATH (optional)

if test -z "$my_script"; then ...; fi
. "$my_script"

或者,只需PATH在脚本顶部设置所需的值。一旦您的初始脚本运行,您就没有理由不能设置PATH.我倾向于在我的许多脚本中这样做,只是为了让我知道环境是合理的。

相关内容