两个问题:如何将此脚本中的shell变量写入其子脚本?
有没有更简单的方法可以做到这一点?
如果你不能按照我的意思行事,我就是:
1)从一个目录列表开始,这些目录的名称将存储为$ i
所取的值2)cd'ing到$ i的每个值并且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
答案 0 :(得分: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
(我会使用base-64编码,留给我自己的设备):
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
{1}},如果遗留任何内容,则会进入$junk
。如果你准确地生成了数据,就不会有任何垃圾;但有时你必须处理其他人的数据。
答案 1 :(得分:1)
如果生成的脚本是临时的,我不会使用文件。此外,将它们调整为可执行的声音不安全。当我需要并行编写脚本时,我使用了一个bash脚本来形成一组命令(在一个数组中,将数组拆分为两个,然后将数组内爆)到一个\n
- 分隔的字符串,然后传递给它到一个新的bash实例。
基本上,在bash:
for orig in "$@"
do
commands="$commands echo \"echoeing stuff here for arguments $orig\" \n"
done
echo -e $commands |bash
还有一个小提示:如果脚本不需要监督,请在管道&
之后输入bash
以使您的第一个脚本退出并完成剩下的工作分叉背景。< / p>
答案 2 :(得分:1)
如果您导出变量
export VAR1=FOO
它将出现在任何子流程中。
如果你看一下init脚本/etc/init..d/*,你会注意到很多来源的文件充满了“外部”定义。您可以设置这样的文件,让您的子脚本来源这些文件。