我正在尝试远程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
答案 0 :(得分:2)
为了构建一个将执行该服务器的命令行,实际上没有必要反复ssh到您的服务器。只需ssh一次,并给它应该运行的脚本。
为了简化一点,没有必要使用find
。 find ~/backup/ -maxdepth 1 -type d
甚至没有按顺序生成列表,因此简单的glob ~/backup/*/
可能更好。
假设你在服务器上有bash,
ssh "$bkuser@$bkserver" \
'dirs=(~/backup/*/);
if ((${#dirs[@]} > 4)); then
echo rm -rvf "${dirs[@]:4}";
fi'
可能会做你想要的。 (为了便于阅读,分成几行;可以在一行中输入所有内容,省略行继续符。)
答案 1 :(得分:1)
'
和"
之间的主要区别在于双引号中的变量被替换,但在单引号中没有变量被替换,并且$()
不会被执行。
因此,要构建要在服务器上执行的命令,您需要将其放入双引号中,因为您需要$()
才能工作:
ssh "$BKUSER"@"$BKSERVER" "echo rm -rvf '$(ssh "$BKUSER"@"$BKSERVER" "find ~/backup/ -maxdepth 1 -type d | head -'${COUNT}'")"
您基本上必须切换单引号和双引号:最外面的引号必须是双引号,以便$()
起作用并替换变量。命令在服务器上工作所需的引号可以是单引号,因为服务器上没有发生变量替换,所有操作都在命令发送之前完成。
您可能想知道为什么'$(ssh ...)'
无论是单引号还是有效。实际上,它是双引号!这里的单引号不是引号,它们只是双引号内的纯文本。它们只被解释为服务器上的单引号。