대규모 출력 리디렉션에서 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

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를 사용하는 경우에는 아무런 문제가 발생하지 않습니다.

관련 정보