2016-05-30 40 views
2

在script.sh,更換「源文件」,其內容,擴大變量,在bash

source a.sh 
source b.sh 

CMD1 
CMD2 
CMD3 

我怎能取代source *.sh與他們的內容(不執行命令)? 我想知道在找到文件並擴展所有變量之後,bash解釋器執行的是什麼。

我知道我可以使用set -n -v或運行bash -n -v script.sh 2>output.sh,但這不會替代源命令(如果a.sh或b.sh包含變量,則更少)。

我想使用一個子shell,但仍然不擴展源代碼行。在源代碼行之前和之後,我嘗試了set +n +vset -n -v的組合,但仍然無效。

我打算使用ssh將輸出發送到遠程機器。 我可以使用<<output.sh將內容傳送到ssh命令中,但我無法以超級用戶身份登錄到遠程計算機,但我是一個sudoer。 因此,我想我可以創建腳本,並把它作爲(使用that clever trickbase64 script | ssh remotehost 'base64 -d | sudo bash'

是否有解決方案base64編碼字符串? 或者你有更好的主意嗎?

回答

2

你可以做這樣的事情:

inline.sh:

#!/usr/bin/env bash 
while read line; do 
    if [[ "$line" =~ (\.|source)\s+.+ ]]; then 
     file="$(echo $line | cut -d' ' -f2)" 
     echo "$(cat $file)" 
    else 
     echo "$line" 
    fi 
done < "$1" 

注意這個假設存在source d文件,並且不處理錯誤。你也應該處理可能的hashbangs。如果sourced文件本身包含source,則需要遞歸應用腳本,例如,像(未測試):

while egrep -q '^(source|\.)' main.sh; do 
    bash inline.sh main.sh > main.sh 
done 

測試一下

main.sh:

source a.sh 
. b.sh 

echo cc 
echo "$var_a $var_b" 

a.sh:

echo aa 
var_a="stack" 

b.sh:

echo bb 
var_b="overflow" 

結果:

bash inline.sh main.sh 

echo aa 
var_a="stack" 
echo bb 
var_b="overflow" 

echo cc 
echo "$var_a $var_b" 

bash inline.sh main.sh | bash 

aa 
bb 
cc 
stack overflow 

順便說一句,如果你只是想看看執行什麼樣的bash,你可以運行

bash -x [script] 

或遠程

ssh [email protected] -t "bash -x [script]" 
+0

您是否嘗試過解決方案,當一個。 sh定義了一個變量,main.sh在'echo cc'之後調用它? 我不認爲這個變量會被擴大。 是的,我已經知道-x。 該腳本是爲了在遠程機器上運行,而不是我的,但我想以編程方式編寫它(即使用變量和某種包含) –

+0

更新了答案。該值不需要擴展,我們只需要將其定義內聯(除非源文件包含它們自己的'source')。在這種情況下,爲什麼遠程和本地有區別?例如。你可以使用'ssh user @ host -t「bash -x -c'echo hi'」' – dimid