我正在尝试执行以下命令:
$ ssh root@10.10.10.50 "tail -F -n 1 $(ls -t /var/log/alert_ARCDB.log | head -n1 )"
ls: cannot access /var/log/alert_ARCDB.log: No such file or directory
tail: cannot follow `-' by name
当我分别登录ssh然后执行
时,请注意返回的错误tail -F -n 1 $(ls -t /var/log/alert_ARCDB.log | head -n1 )"
见下文:
# ls -t /var/log/alert_ARCDB.log | head -n1
/var/log/alert_ARCDB.log
为什么会发生这种情况以及如何解决它。我试图在一行中这样做,因为我不想创建一个脚本文件。
非常感谢
答案 0 :(得分:0)
在执行命令之前,发生了Shell参数扩展。
这是一个简单的例子。如果我打字......
ls "$HOME"
... shell首先将$HOME
替换为我的主目录的路径,然后运行类似ls /home/larsks
的内容。 ls
命令不知道命令行最初有$HOME
。
如果我们看看你的命令......
$ ssh root@10.10.10.50 "tail -F -n 1 $(ls -t /var/log/alert_ARCDB.log | head -n1 )"
......我们看到你处于完全相同的情况。在执行 $(ls -t ...)
之前,ssh
表达式已展开。换句话说,该命令正在运行本地系统。
您可以使用单引号禁止本地系统上的shell扩展。例如,运行:
echo '$HOME'
将产生:
$HOME
所以你可以跑:
ssh root@10.10.10.50 'tail -F -n 1 $(ls -t /var/log/alert_ARCDB.log | head -n1 )'
但这里还有另一个问题。如果/var/log/alert_ARCDB.log
是文件,那么您的命令没有任何意义:在单个文件上调用ls -t
无法获取任何内容。
如果alert-ARCDB.log
是目录,则会遇到其他问题。 ls /some/directory
的结果是没有任何目录前缀的文件名列表。如果我运行类似的东西:
ls -t /tmp
我会得到像
这样的输出file1
file2
如果我这样做:
tail $(ls -t /tmp | head -1)
我最终得到的命令如下:
tail file1
这会失败,因为我的当前目录中没有file1
。
答案 1 :(得分:0)
一种方法是将要执行的命令传递给ssh。实现这一目标的一种简单方法是首先创建一个将回显您想要执行的命令的函数:
remote_commands()
{
echo 'cd /var/log/alert_ARCDB.log'
echo 'tail -F -n 1 "$(ls -t | head -n1 )"'
}
cd
将允许您使用ls
列出的相对路径。单引号确保所有内容都按原样发送到远程shell,不会发生本地扩展。
然后你可以做
ssh root@10.10.10.50 bash < <(remote_commands)
这假设alert_ARCDB.log
是一个目录(否则我不确定为什么你想在之后添加head -n1
。)