shell 执行命令时预期脚本失败

00jrzges  于 2023-08-07  发布在  Shell
关注(0)|答案(2)|浏览(132)

我有一个预期的脚本,它似乎是失败的...当我使用put来显示命令的内容时,它看起来很好,但是exec似乎在做一些我在过去几分钟里一直在努力的事情…有什么想法吗?

#!/usr/bin/expect -f

    set recipients {
        "abc@abc.com"
        "xyz@abc.com"
    }
    set body "Success!"
    set subject "File Upload Status"
    set email_sender "EmailSender <Email.Sender@abc.com>"
    set smtp_server "smtp://webmail.abc.com"
    set recipient_list [join $recipients ","]
    set cmd "echo \"$body\" | mailx -s \"$subject\" -r \"$email_sender\" -S smtp=$smtp_server \"$recipient_list\""
    puts $cmd

    # Execute the mailx command
    exec $cmd

字符串
故障发生在exec,我看到的错误是这样的:

> ./test.expect
echo "Success!" | mailx -s "File Upload Status" -r "EmailSender <Email.Sender@abc.com>" -S smtp=smtp://webmail.abc.com "abc@abc.com,xyz@abc.com"
couldn't execute "echo "Success!" | mailx -s "File Upload Status" -r "EmailSender <Email.Sender@abc.com>" -S smtp=smtp:/webmail.abc.com "abc@abc.com,xyz@abc.com"": no such file or directory
    while executing
"exec $cmd"
    (file "./test.expect" line 16)


我做错了什么?
我试着在最后一行的$cmd周围加上双引号和单引号,但是没有效果。
我不明白的是为什么smtp服务器在执行时表现不同,而不是在我运行puts命令时...
如果我把最后一行改为

exec sh -c $cmd


一切正常。为什么我需要显式调用sh -c,有什么方法可以避免它吗?

8yoxcaq7

8yoxcaq71#

tclexec可以设置管道,但是您必须使用|参数分隔单独的命令,而不是将其全部作为单个字符串传递。

exec echo $body | mailx -s $subject -r $email_sender -S smtp=$smtp_server $recipient_list

字符串
但你在这里其实不需要。<< value就像一个shell;将流水线中第一条命令的标准输入设置为该值;不需要echo
例如:

exec mailx -s $subject -r $email_sender -S smtp=$smtp_server $recipient_list << $body


应该可以注意,不必引用变量。tcl比大多数shell有更合理的扩展规则;这里不需要他们
您还可以避免将列表收件人联接到单个字符串中; mailx可以将单个电子邮件地址作为参数,而参数扩展({*}list)将拼接列表的内容作为单个参数:

exec mailx ... {*}$recipients << $body

iezvtpos

iezvtpos2#

您需要显式调用sh -c,因为(a)您没有尝试执行命令;您正在运行一个shell管道,并且(B)即使对于单个命令,exec也需要一个数组,而不是字符串参数。也就是说,这些工作:

expect1.1> exec date
Fri Jun 30 09:11:55 PM EDT 2023
expect1.2> exec echo "hello world"
hello world

字符串
但这不会:

expect1.1> exec "echo hello world"
couldn't execute "echo hello world": no such file or directory
    while executing
"exec "echo hello world""


因为没有名为echo hello world的命令。
当然,如果你想利用特定于shell的语法,比如管道(|),i/o重定向(<>等)等等,那么你需要实际使用shell:

expect1.1> exec sh -c "echo hello world | sed s/world/people/"
hello people

相关问题