2010-09-05 211 views
0

有兩個問題:如何將此腳本的shell變量寫入其子腳本?編寫shell腳本的shell腳本

有沒有更簡單的方法來做到這一點?

如果你不能按照我在做什麼,我:

1)開始,他們的名字將被存儲爲$我

2所值的目錄列表)CD 「荷蘭國際集團爲$我每天值,並通過使用echo貓

4)和貓用目錄的名稱ls'ing其內容

3)呼應其內容到一個新的腳本編寫一個新的腳本包含$ i的ls'd值並將它們全部發送到博客電子郵件地址叫做$ [email protected]

#/bin/sh 
read -d '' commands <<EOF 

#list of directories goes here 
dir1 
dir2 
dir3 
etc...  

EOF 

for i in $commands 
do 

cd $SPECIALPATH/$i 
echo ("#/bin/sh \n read -d '' directives <<EOF \n") | cat >> $i.sh 
ls | cat >> $i.sh 
echo ("EOF \n for q in $directives \n do \n uuencode $q $q | sendmail $i \n done \n") | cat >> $i.sh 
# NB -- I am asking the script to write the shell variable $i into the new 
# script, called $i.sh, as the email address specified, in the middle of an 
# echo statement... I am well aware that it doesn't work as is 
chmod +x $i.sh 
./$i.sh  

done 
+1

爲什麼你必須寫腳本呢?你不能執行代碼嗎? – alternative 2010-09-05 12:37:53

回答

5

你濫用貓科動物 - 你應該簡單地重定向,而不是管道到cat附加。

您可以通過將通過管道直接導入到shell的單個I/O重定向綁定到文件的所有輸出來避免中間文件$i.sh - 無需中間文件清理(您沒有顯示發生)或chmod操作。

我會做這個使用括號:

{ 
echo "..." 
ls 
echo "..." 
} | sh 

然而,當我看着在表單中的腳本,我意識到,是沒有必要的。我已經離開你的腳本的初始部分不變,但環就是這樣變得極其簡單:

#/bin/sh 
read -d '' commands <<EOF 

#list of directories goes here 
dir1 
dir2 
dir3 
etc...  

EOF 

for i in $commands 
do 
    (
    cd $SPECIALPATH/$i 
    ls | 
    while read q 
    do uuencode $q $q | sendmail $i 
    done 
    ) 
done 

我假設sendmail命令的作品 - 這不是我想嘗試發送電子郵件的方式。我可能會使用mailx或類似的東西,我會避免使用過於uuencode(我會使用一個基於64位編碼,留給我自己的設備):

do uuencode $q $q | mailx -s "File $q" [email protected] 

的腳本也可以使用各地的括號cd命令。這意味着cd命令以及後續內容在子shell中運行,所以父級腳本不會更改目錄。在這種情況下,對於$ SPECIALDIR的絕對路徑名,這並不重要。但作爲一般規則,如果隔離目錄更改,它通常會使生活更輕鬆。

我可能進一步簡化它仍然一般重用(雖然我需要添加一些東西,以確保SPECIALPATH設置正確):

#/bin/sh 

for i in "[email protected]" 
do 
    (
    cd $SPECIALPATH/$i 
    ls | 
    while read q 
    do uuencode $q $q | sendmail $i 
    done 
    ) 
done 

我然後調用它

script-name $(<list-of-dirs) 

這意味着,如果不編輯腳本,它可以重複用於任何目錄列表。


中間體步驟1:

for i in $commands 
do 
    (
    cd $SPECIALPATH/$i 
    { 
    echo "read -d '' directives <<EOF" 
    ls 
    echo "EOF" 
    echo "for q in $directives" 
    echo "do" 
    echo " uuencode $q $q | sendmail $i" 
    echo "done" 
    } | 
    sh 
    ) 
done 

個人而言,我發現更容易閱讀生成的腳本,如果生成該代碼使生成的腳本明確的 - 使用多個回波命令。這包括縮進代碼。

中間體。步驟2:

for i in $commands 
do 
    (
    cd $SPECIALPATH/$i 
    { 
    ls | 
    echo "while read q" 
    echo "do" 
    echo " uuencode $q $q | sendmail $i" 
    echo "done" 
    } | 
    sh 
    ) 
done 

我並不需要讀出的數據到一個變量,以便通過在列表中每個項目到步驟一次 - 簡單地依次讀取每一行。 while read機制通常也用於將一條線分成多個變量:while read var1 var2 var3 junk將第一個字段讀入$var1,第二個字段寫入$var2,第三個字段寫入$var3,如果剩下任何內容,則會寫入$junk。如果您已經準確地生成了數據,則不會有垃圾;但有時你必須處理其他人的數據。

+0

謝謝。這是一個很好的答案。 – magnetar 2010-09-05 18:43:25

1

如果生成的腳本是臨時的,我不會使用文件。此外,chmoding他們可執行的聲音不安全。當我需要平行我的腳本時,我使用了一個bash腳本來形成一組命令(在一個數組中,將數組分成兩部分,然後將數組分解)到一個單獨的字符串中,然後將它傳遞給一個新的bash實例。

基本上,在bash:

for orig in "[email protected]" 
do 
    commands="$commands echo \"echoeing stuff here for arguments $orig\" \n" 
done 

echo -e $commands |bash 

和一個小提示:如果腳本不需要監督,扔在管道bash&,使您的第一個腳本退出,做的其餘部分工作分叉的背景。

1

如果導出一個變量

export VAR1=FOO 

它會出現在所有的子進程。

如果你看看init腳本,/etc/init..d/*,你會注意到許多源文件充滿了「外部」定義。你可以像這樣設置一個文件並讓你的子腳本獲取這些文件。