foreach 循环中的空值 - TCL - unix 脚本
empty value in foreach loop - TCL - unix script
即使列表包含值,我在 foreach 循环的以下脚本中得到变量 $tclItem 的空值。
你能检查一下我遗漏了什么吗?
FTP_USER="xxxxx"
FTP_SERVER="xxxxx"
FTP_PWD="xxxx"
FTP_DROP_DIR="DROP/Archive"
LOGFILE="\tmp\log.txt"
FILES_TO_ARCHIVE="$(cat $LOGFILE | grep '.txt' | awk ' !/Fetching/' | tr -d '\r') "
echo "Files to Archive..."
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo $FILES_TO_ARCHIVE
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
expect <<END
spawn sftp $FTP_USER@$FTP_SERVER
expect "*password: "
send "$FTP_PWD\r";
expect "sftp> "
foreach tclItem {$FILES_TO_ARCHIVE } {
#puts $tclItem
send "ls $FTP_DROP_DIR/$tclItem\r"
expect "sftp> "
};
send "quit\r"
END
这是我收到的输出。
Files to Archive.....
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
test1.txt test2.txt test3.txt test4.txt
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
spawn sftp abcdef@sftp.server.com
abcdef@sftp's password:
sftp> ls DROP/Archive/
sftp> ls DROP/Archive/
sftp> ls DROP/Archive/
sftp> ls DROP/Archive/
sftp> invalid command name "test2.txt"
while executing
"test2.txt"
与其使用字符串替换将数据注入代码(这种做法充满安全问题),不如通过环境将变量从 bash
传递到 expect
。
# Environment variables should be lowercase except for special/reserved names meaningful
# to the operating system; http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
ftp_user="xxxxx"
ftp_server="xxxxx"
ftp_pwd="xxxx"
ftp_drop_dir="DROP/Archive"
logfile="/tmp/log.txt"
files_to_archive="$(awk '/[.]txt/ && !/Fetching/' <"$logfile" | tr -d '\r')"
export ftp_user ftp_server ftp_pwd ftp_drop_dir files_to_archive
expect <<'END'
spawn sftp $env(ftp_user)@$env(ftp_server)
expect "*password: "
send "$env(ftp_pwd)\r";
expect "sftp> "
set fileList [split $env(files_to_archive) "\n"]
foreach tclItem $fileList {
send "ls $env(ftp_drop_dir)/$tclItem\r"
expect "sftp> "
};
send "quit\r"
END
注:
- 使用
export
会导致 shell 变量可用作子流程中的环境变量。在期望中,$env(foo)
让人读取环境变量 foo
.
- 使用
<<'EOF'
而不是 <<EOF
会导致 bash 将代码原样传递给 expect
完全 ,而不变化。 (因此,$tclItem
仍然是 $tclItem
,而不是在 expect
甚至开始之前被替换为空字符串。
即使列表包含值,我在 foreach 循环的以下脚本中得到变量 $tclItem 的空值。
你能检查一下我遗漏了什么吗?
FTP_USER="xxxxx"
FTP_SERVER="xxxxx"
FTP_PWD="xxxx"
FTP_DROP_DIR="DROP/Archive"
LOGFILE="\tmp\log.txt"
FILES_TO_ARCHIVE="$(cat $LOGFILE | grep '.txt' | awk ' !/Fetching/' | tr -d '\r') "
echo "Files to Archive..."
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo $FILES_TO_ARCHIVE
echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
expect <<END
spawn sftp $FTP_USER@$FTP_SERVER
expect "*password: "
send "$FTP_PWD\r";
expect "sftp> "
foreach tclItem {$FILES_TO_ARCHIVE } {
#puts $tclItem
send "ls $FTP_DROP_DIR/$tclItem\r"
expect "sftp> "
};
send "quit\r"
END
这是我收到的输出。
Files to Archive.....
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
test1.txt test2.txt test3.txt test4.txt
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
spawn sftp abcdef@sftp.server.com
abcdef@sftp's password:
sftp> ls DROP/Archive/
sftp> ls DROP/Archive/
sftp> ls DROP/Archive/
sftp> ls DROP/Archive/
sftp> invalid command name "test2.txt"
while executing
"test2.txt"
与其使用字符串替换将数据注入代码(这种做法充满安全问题),不如通过环境将变量从 bash
传递到 expect
。
# Environment variables should be lowercase except for special/reserved names meaningful
# to the operating system; http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
ftp_user="xxxxx"
ftp_server="xxxxx"
ftp_pwd="xxxx"
ftp_drop_dir="DROP/Archive"
logfile="/tmp/log.txt"
files_to_archive="$(awk '/[.]txt/ && !/Fetching/' <"$logfile" | tr -d '\r')"
export ftp_user ftp_server ftp_pwd ftp_drop_dir files_to_archive
expect <<'END'
spawn sftp $env(ftp_user)@$env(ftp_server)
expect "*password: "
send "$env(ftp_pwd)\r";
expect "sftp> "
set fileList [split $env(files_to_archive) "\n"]
foreach tclItem $fileList {
send "ls $env(ftp_drop_dir)/$tclItem\r"
expect "sftp> "
};
send "quit\r"
END
注:
- 使用
export
会导致 shell 变量可用作子流程中的环境变量。在期望中,$env(foo)
让人读取环境变量foo
. - 使用
<<'EOF'
而不是<<EOF
会导致 bash 将代码原样传递给expect
完全 ,而不变化。 (因此,$tclItem
仍然是$tclItem
,而不是在expect
甚至开始之前被替换为空字符串。