2017-05-03 61 views
0

我有一个应该检查用户是否定义了函数的bash脚本,如果没有函数存在,将定义函数在其~/.bashrc文件。我简化了代码的显示目的。下面是该脚本:无法检测是否从脚本定义了shell函数

#!/bin/bash 

brc="$HOME/.bashrc" 

exists=false 

# check if the function exists 
if [ -n "$(type -t cs)" ] && [ "$(type -t cs)" = function ]; then 
    exists=true 
fi 

if [ "$exists" = false ]; then 
    echo "true" 
else 
    echo "false" 
fi 

通过大量的测试echo,我已经想通了,不管叫cs功能是否存在对我来说,第一个条件语句始终计算为false。奇怪的是,当我将这些行直接复制并粘贴到我的shell中而没有运行脚本时,该行的计算结果为true!请帮忙。

+0

'bash -x yourscript'是你的朋友在这里。 –

+0

...说,函数不会从父进程继承,除非您导出它们,所以当您运行脚本时,它无法知道哪些函数在交互式shell中定义或未定义。 –

+0

但是,然后OP在'.bashrc'中定义了这个函数,并且它应该在_sourcing_上对脚本可用? – Inian

回答

2

除非它们已经用export -f导出,否则对于壳体的单个实例本地的功能是。你的脚本运行在不同的实例中。

如果您希望您的命令能够确定哪些shell函数处于活动状态,则应该将其写入现有shell而不是作为外部命令执行,或者将其定义为shell函数本身。

你也源.bashrc,如果你愿意来对付你的脚本的行为被其副作用修改:

brc="$HOME/.bashrc" 
[[ -e "$brc" ]] && source "$brc" 
+0

在定义那里的函数之后,将'export -f cs'添加到我的'.bashrc'文件中有任何问题吗?在环境中重复定义“cs”的任何内容? –

+0

不是 - 每个函数都有一个环境变量,所以在这方面你是安全的。导出函数唯一真正的困难是由于shellshock的原因,格式已经改变,所以如果你使用不同版本的bash(因为它的股票很古老,在OS X上相当普遍),一个导出的函数可能不会被其他人认可。 –

1

默认.bashrc不会被加载非交互shell中,例如,这是从我的(默认).bashrc

# If not running interactively, don't do anything 
case $- in 
    *i*) ;; 
     *) return;; 
esac 

或者你可能有类似:

# If not running interactively, don't do anything 
[ -z "$PS1" ] && return 

因此,您需要弄清楚如何将.bashrc加载到非交互式shell(取决于它在系统中检查的方式)或从另一个文件中获取函数。