编写shell脚本的Shell脚本

mag*_*tar 0 unix linux shell

两个问题:如何将此脚本中的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)

Jon*_*ler 5

你经常滥用猫科动物 - 你应该简单地重定向,而不是管道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.如果你准确地生成了数据,就不会有任何垃圾; 但有时你必须处理其他人的数据.