两个问题:如何将此脚本中的shell变量写入其子脚本?
有没有更简单的方法来做到这一点?
如果你不能遵循我正在做的事情,我是:
1)从一个目录列表开始,其名称将存储为$ i所取的值
2)cd'ing到$ i的每个值并且ls'ing其内容
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
Run Code Online (Sandbox Code Playgroud)
你经常滥用猫科动物 - 你应该简单地重定向,而不是管道cat附加.
您可以$i.sh通过将单个I/O重定向捆绑到文件的所有输出来捆绑所有输出来避免中间文件,该重定向直接管道到shell中 - 不需要清理中间文件(您没有显示发生这种情况)或者chmod操作.
我会用大括号做到这一点:
{
echo "..."
ls
echo "..."
} | sh
Run Code Online (Sandbox Code Playgroud)
但是,当我以那种形式查看脚本时,我意识到这没有必要.我已经保留了脚本的初始部分,但循环非常简单,如下所示:
#/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
Run Code Online (Sandbox Code Playgroud)
我假设sendmail命令有效 - 这不是我尝试发送电子邮件的方式.我可能会使用mailx或类似的东西,我也避免使用uuencode(我使用base-64编码,留给我自己的设备):
do uuencode $q $q | mailx -s "File $q" $i@tumblr.com
Run Code Online (Sandbox Code Playgroud)
该脚本还使用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
Run Code Online (Sandbox Code Playgroud)
然后我可以调用它:
script-name $(<list-of-dirs)
Run Code Online (Sandbox Code Playgroud)
这意味着如果不编辑脚本,它可以重用于任何目录列表.
中级步骤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
Run Code Online (Sandbox Code Playgroud)
就个人而言,如果生成的代码使生成的脚本清晰 - 使用多个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
Run Code Online (Sandbox Code Playgroud)
我不需要将数据读入变量,以便逐步遍历列表中的每个项目 - 只需依次读取每一行.该while read机制通常也可用于将一条线分成多个变量: while read var1 var2 var3 junk将第一个字段读入$var1,第二个字段读入$var2,第三个字段输入,$var3如果有任何遗留,则进入$junk.如果你准确地生成了数据,就不会有任何垃圾; 但有时你必须处理其他人的数据.