
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
が拡張されていない場合は、コマンドを置き換えなくてもうまく機能しますが、必要です。$()
$file
どうすれば解決できますか?
情報:
これはスクリプトではなく、私の~/.bash_profileにあります。
これは(他のスクリプトのうち)gitリポジトリにあるスクリプトです~/bash_profile
(私は設定ソースを使用するインストールスクリプトを持っています$PWD
)。したがって、人々はgitリポジトリにCDを送るのではなく、このコマンドを直接使うことができます。他の多くのもの)彼らには適用されません)。
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
達成しようとしている目標の説明と、入力と出力の例を含めるように質問を変更できる場合は、ここにいる誰かが要件を満たすようにコードを書き換える方法を提案できます。