我有一个if
语句来计算文件并删除除了最新的三个文件之外的所有文件。但我想远程运行这个命令。如何ssh
与if
条件结合?
我试过这个但没有成功。
#!/bin/bash
ssh -t [email protected] "cd /var/www/test.com/backup ;
if [ $(ls | wc -l) -lt 3 ]
then
echo "Less"
else [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]
echo "deleted"
fi"
我得到的错误:
ls: 无法访问 *.tgz: 没有这样的文件或目录
是的,您可以通过以下方式执行复杂的脚本
ssh
此示例使用 bash here 文档来生成命令字符串。在任何情况下,通过 ssh 传递脚本都容易出错,因为引用和转义变量很困难(注意命令前的反斜杠)。如果脚本太复杂,最好通过复制它
scp
,然后在目标主机上执行。我没有尝试修复您的脚本,但这里有一个关于如何在远程主机上进行计数和删除的示例:
这
ls -t *.tgz
将不起作用,因为globbing只发生在本地系统上。同样ls
用于计数文件也不是一个好主意,因为它还会返回.
,..
和目录之类的条目。注意:这里的问题实际上有两层。一个是“我想在可通过 SSH 访问的远程服务器上执行一项重要任务”。另一个是“我正在尝试将一个复杂的字符串传递给一个命令,但参数最终与我的意图不同。” 我在回答低级问题时没有讨论解决高级问题所使用的方法是否“正确”(方便、不易出错、安全等)。正如其他答案和评论所表明的那样,很可能不是。
您的命令行大多是正确的;您只需要稍微更改报价即可。
主要问题是双引号字符串被您的本地 shell 扩展,因此这些
$(...)
部分将在您的本地系统上进行评估。要将它们传递给远程系统,您必须将脚本括在单引号中。您还有一些嵌入的引号。在您的原始脚本中,有两个
echo
s 的参数;如果将外引号更改为单引号,它将是 awk 脚本。这些有效地导致引号被省略,这不会打扰echo
s,但它会弄乱 awk 脚本,因为大于号将成为输出重定向。因此,将外引号更改为单引号后,将其更改为双引号。这是您的脚本,引用固定。该脚本可能有其他问题,我只是修复了语法。
我认为这整个复杂的引用内容足以证明不使用它,而是使用脚本。如果您想避免多个
ssh
连接,请将脚本通过管道传输到另一台主机并让它在一个命令中运行:本地文件,说
myscript.sh
:然后:
或者(避免对 cat 的无用使用):
这会将本地脚本通过管道
myscript.sh
传输到远程端,在那里它被重定向到(临时)文件/tmp/ms.sh
,执行并最终删除。注意:我没有检查原始脚本是否有错误,只是想展示一下这个想法。不需要容易出错的引用,并且脚本中的所有命令都在远程端执行。
我更愿意将脚本放在远程实例上并通过 ssh 执行它,但这是我的建议,如何以您想要的方式完成:
笔记:
-lt
被替换-le
。eval
- 通过连接参数构造命令。\"
在$COMMAND{1..3}
表达式中添加这些额外的引号,但我决定添加它们。