データベースクエリを実行し、結果を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
StartDate
、StopDate
およびは、あなたReportDir
が示したスクリプトに設定されていないため、スクリプト全体ではないと仮定します。だから:
$ 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
使用を検討してくださいSSHパス代わりに。
SSHPassは、プロンプトを使用せずにSSHパスワードを提供できる小さなユーティリティです。これはスクリプトに非常に便利です。 SSHPassはマルチユーザー環境での使用には適していません。開発システムでSSHPassを使用している場合、問題は発生しません。