2010-09-05 214 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/*,你会注意到许多源文件充满了“外部”定义。你可以像这样设置一个文件并让你的子脚本获取这些文件。