不确定如何在bash脚本中使用'

时间:2016-06-08 21:54:57

标签: bash

我正在尝试远程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

2 个答案:

答案 0 :(得分:2)

为了构建一个将执行该服务器的命令行,实际上没有必要反复ssh到您的服务器。只需ssh一次,并给它应该运行的脚本。

为了简化一点,没有必要使用findfind ~/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 ...)'无论是单引号还是有效。实际上,它是双引号!这里的单引号不是引号,它们只是双引号内的纯文本。它们只被解释为服务器上的单引号。