2017-05-03 42 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(取決於它在系統中檢查的方式)或從另一個文件中獲取函數。

相關問題