我有几台服务器,其中有几个文件,其中包含我需要解析的部署日期信息,并获取 2 个月或更早的文件的本地副本。
#!/bin/bash
# split on new line not space
# don't want to quote everything
# globbing desired
IFS=$'\n'
servers=(
blue
red
)
parseDate() {
grep 'deploy_date:' $file | \
sed ... | \
# much more in here...
}
getOldFiles() {
local #all vars
currentDateInSecs=$(date +%s)
twoMonthsInSecs=526000
for server in ${servers[@]}; do
oldfile=$(
ssh $server "
$(declare -f parseDate)
for file in /dir/$server/file*; do
dateInSecs=$(date -jf '%b/%e/%Y' $(parseDate) +%s)
timeDiff=$((\$currentDateInSecs - \$dateInSecs))
((\$timeDiff >= \$twoMonthsInSecs)) &&
cat \$file
done
"
)
[ -n $oldFile ] &&
cat $oldFile ~/oldFiles/${server}-${file}.txt
done
问题:
当前的问题是dateInSecs=$(date -jf '%b/%e/%Y' $(parseDate \$file) +%s)
.
当 变量parseDate \$file
中的 is未扩展时,无需命令替换即可正常工作,但我需要它。$()
$file
我该如何解决?
信息:
这不是脚本,它们在我的 ~/.bash_profile 中
这是 git 存储库中的一个脚本(以及其他脚本),它源自~/bash_profile
(我有一个使用设置源的安装脚本$PWD
),因此人们可以直接使用这些命令,而不是 cd'ing 到 git 存储库(其中还有许多其他内容)不适用于他们)。
从 Macos 到 CentOS 服务器运行。
答案1
所有可以在oldfile=$(...)
命令替换中扩展的内容都将被扩展前你ssh。$()
如果您希望它们在远程而不是本地运行,则需要转义各种内部。您想要在远程评估的任何内容都需要转义。尝试:
oldfile=$(
ssh $server "
$(declare -f parseDate)
for file in /dir/$server/file*; do
dateInSecs=\$(date -jf '%b/%e/%Y' \$(parseDate \$file) +%s)
timeDiff=\$(($currentDateInSecs - \$dateInSecs))
((\$timeDiff >= \$twoMonthsInSecs)) &&
cat \$file
done
"
)
另外,虽然 BSDdate
有此-j
选项,但 GNUdate
没有。由于您正在连接到 CentOS 计算机,因此您可能想要更改
dateInSecs=\$(date -jf '%b/%e/%Y' \$(parseDate \$file) +%s)
到
dateInSecs=\$(date \$(parseDate \$file) +%s)
但我们需要查看您获得的确切格式才能parseDate
确定。
答案2
请小心使用双引号和单引号。如果使用双引号,则在执行命令之前将计算所有$variables
和表达式。$( … )
例如:
ssh $server " $(declare -f parseDate) for file in /dir/$server/file*; do dateInSecs=$(date -jf '%b/%e/%Y' $(parseDate \$file) +%s) timeDiff=$((\$currentDateInSecs - \$dateInSecs)) ((\$timeDiff >= \$twoMonthsInSecs)) && cat \$file done "
在这里,如果$server
是remoteHost
,这将被准备成这样前被传递ssh
到远程$server
:
ssh remoteHost "
parseDate() { … }
for file in /dir/remoteHost/file*; do
dateInSecs=
timeDiff=
((\$timeDiff >= \$twoMonthsInSecs)) && cat \$file
done
"
在 RemoteHost 本身上,您将尝试执行如下操作:
parseDate() { … }
for file in /dir/remoteHost/file*; do
dateInSecs=
timeDiff=
(( >= )) && cat $file
done
如果您可以修改您的问题以包括对您想要实现的目标的解释以及示例输入和输出,那么这里的某人可能会建议如何重写您的代码以满足要求。