我正在尝试远程通过 SSH 连接到服务器并删除 x 数量的备份,具体取决于我们设置在脚本中保留的数量。
#!/bin/bash
BKUSER=4582
BKSERVER=int-backup2.domain.com
DELETEMORETHAN=$(ssh "$BKUSER"@"$BKSERVER" 'find ~/backup/ -maxdepth 1 -type d | wc -l')
if [ "$DELETEMORETHAN" -gt 4 ] ; then
COUNT=$(echo "$DELETEMORETHAN - 4" | bc -l)
ssh "$BKUSER"@"$BKSERVER" 'echo rm -rvf "$(ssh "$BKUSER"@"$BKSERVER" 'find ~/backup/ -maxdepth 1 -type d | head -"${COUNT}"')'
fi
在此示例中,我尝试保留 4 个最新备份。 我在
ssh "$BKUSER"@"$BKSERVER" 'echo rm -rvf "$(ssh "$BKUSER"@"$BKSERVER" 'find ~/backup/ -maxdepth 1 -type d | head -"${COUNT}"')'
我试图使用:https://github.com/koalaman/shellcheck/wiki/SC2026 但它没有帮助,因为' 没有正确分组,我卡住了!
丹尼斯-B:
[root@ngx /]# ./test
bash: -c: line 0: unexpected EOF while looking for matching `''
bash: -c: line 3: syntax error: unexpected end of file
构建将执行该服务器的命令行,反复 ssh 进入您的服务器真的没有意义。只需 ssh 一次,并为其提供应该运行的脚本。
为了简化一点,没有真正需要使用 find
. find ~/backup/ -maxdepth 1 -type d
甚至没有按顺序生成列表,因此简单的全球~/backup/*/
可能更好。
假设你在服务器上有bash,
ssh "$bkuser@$bkserver"
'dirs=(~/backup/*/);
if ((${#dirs[@]} > 4)); then
echo rm -rvf "${dirs[@]:4}";
fi'
可能会做你想做的事。(为便于阅读,拆分为几行;可以在一行中键入所有内容,省略行继续符。
'
和 "
之间的主要区别在于,双引号中的变量被替换,但在单引号中,没有变量被替换,并且不执行$()
。
因此,要构建要在服务器上执行的命令,您需要将其放入双引号中,因为您需要$()
才能工作:
ssh "$BKUSER"@"$BKSERVER" "echo rm -rvf '$(ssh "$BKUSER"@"$BKSERVER" "find ~/backup/ -maxdepth 1 -type d | head -'${COUNT}'")"
你基本上必须切换单引号和双引号:最外面的引号必须是双引号,这样$()
才能工作并替换变量。命令在服务器上工作所需的引号可以是单引号,因为服务器上不会发生变量替换,一切都在发送命令之前完成。
您可能想知道为什么'$(ssh ...)'
尽管是单引号,但它仍然有效。实际上,它是双引号!这里的单引号不是引号,它们只是双引号内的纯文本。它们在服务器上仅被解释为单引号。