大規模出力リダイレクトにおける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 -fbashが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

StartDateStopDateおよびは、あなた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を使用している場合、問題は発生しません。

関連情報