两个问题:如何将此脚本中的shell变量写入其子脚本?
有没有更简单的方法可以做到这一点?
如果你不明白我在做什么,我会:
1)从目录列表开始,这些目录的名称将存储为$i接受的值
2)对$i的每个值进行cd‘’ing,并对其内容进行ls
3)通过cat将其内容回显到带有目录名的新脚本中
4)使用echo和cat编写一个包含$i的ls‘d值的新脚本,并将它们全部发送到一个名为$i@tumblr.com的博客电子邮件地址
#/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发布于 2010-09-05 22:13:00
您滥用猫科动物很多-您应该简单地重定向,而不是管道到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 (我会使用base64编码,留给我自己的设备):
do uuencode $q $q | mailx -s "File $q" $i@tumblr.com该脚本还使用括号将cd命令括起来。这意味着cd命令和随后的命令是在子shell中运行的,因此父脚本不会更改目录。在这种情况下,如果有$SPECIALDIR的绝对路径名,那就没什么关系了。但作为一般规则,如果像这样隔离目录更改,通常会使工作变得更容易。
为了更好地重用,我可能会进一步简化它(尽管我需要添加一些东西来确保SPECIALPATH被适当地设置):
#/bin/sh
for i in "$@"
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就我个人而言,我发现如果生成的代码使生成的脚本清晰-使用多个echo命令,则更容易阅读生成的脚本。这包括缩进代码。
中间步骤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。如果您准确地生成了数据,就不会有任何垃圾;但有时您必须处理其他人的数据。
发布于 2010-09-05 21:48:05
如果生成的脚本是临时的,我就不会使用文件。此外,将它们更改为可执行文件听起来不安全。当我需要并行编写脚本时,我使用bash脚本将一组命令(在数组中,将数组一分为二,然后内爆数组)形成单个\n-separated字符串,然后将其传递给一个新的bash实例。
基本上,在bash中:
for orig in "$@"
do
commands="$commands echo \"echoeing stuff here for arguments $orig\" \n"
done
echo -e $commands |bash 还有一个小技巧:如果脚本不需要监督,那么在管道bash后面抛出一个&,让您的第一个脚本退出,并完成派生后台的其余工作。
发布于 2010-09-05 22:03:35
如果导出变量
export VAR1=FOO它会出现在任何子进程中。
如果您查看init脚本/etc/init..d/*,您会注意到许多脚本都来自另一个充满“外部”定义文件。您可以设置一个这样的文件,并让您的子脚本源这些文件。
https://stackoverflow.com/questions/3646059
复制相似问题