大型输出重定向中的 Bash 脚本顺序混合

大型输出重定向中的 Bash 脚本顺序混合

我有一个脚本,它运行数据库查询并将结果重定向到 csv 文件,在使用 sftp 上传它之后,该文件将被删除,如下所示:

FileName=` echo "report_$StartDate:$StopDate.csv" | sed 's/\ /_/g'`

$DatabaseCommand "$Query" -f CSV | sed 's/"//g' > "$ReportDir/$FileName"

expect<<EOD
set timeout 3600
spawn sftp $USER@$HOST
expect "password:"
send "$PASSWORD\r"
expect "sftp>"
send "put $ReportDir/$FileName\r"
expect "sftp>"
send "bye\r"
EOD

rm -rf $ReportDir/$FileName

我知道最后一行应该更改为rm -f,但我想知道 bash 是否可以在 FileName 行中混合并能够运行以下命令:

rm -rf $ReportDir/

答案1

使用这样的命令,您可能希望防止变量为空,无论这种情况如何发生:

$ cat foo.sh
#!/bin/bash
ReportDir=/somepath
FileNam=$(echo ...) # oops, a typo
# ... 
rm -rf -- "${ReportDir:?}/${FileName:?}"

$ bash -x foo.sh
+ ReportDir=/somepath
++ echo ...
+ FileNam=...
foo.sh: line 5: FileName: parameter null or not set

如果为空或未设置,则扩展${parameter:?message}会退出并出现错误。parameter默认消息通常就可以了,所以我没有在上面的代码中给出一条消息。

或者,只需手动检查,但这很冗长并且仍然容易出现拼写错误:

if [ -z "$FileName" ] ; then
    echo "FileName is empty!" >&2
    exit 1
fi
rm -rf -- "$ReportDir/$FileName"

答案2

由于StartDateStopDateReportDir未在您向我们展示的脚本中设置,因此我假设这不是整个脚本。所以:

$ cat foo.sh
ReportDir=foo
# commands from what you have shown, omitting `expect` and db command
FileName=` echo "report_$StartDate:$StopDate.csv" | sed 's/\ /_/g'`

rm -rf $ReportDir/$FileName
$ bash -ux foo.sh
+ ReportDir=foo
foo.sh: line 2: StartDate: unbound variable
++ sed 's/\ /_/g'
+ FileName=
+ rm -rf foo/

显然它已经膨胀FileName到什么都没有了,然后就跑了rm -rf foo/

答案3

考虑使用sshpass反而。

SSHPass 是一个小型实用程序,允许您在不使用提示符的情况下提供 ssh 密码。这对于脚本编写非常有帮助。 SSHPass 不适合在多用户环境中使用。如果您在开发机器上使用 SSHPass,它不会做任何坏事。

相关内容